I'm not sure if I understood your last comment correctly. As you state two (for me) different things:
- You use plugin.jar (which means to me your java calls javascript functions)
- "I call the same functions from the Javascript" (which means to me your javascript calls java functions)
I assume the later one is the right interpretation.
If you just call java methods (via liveconnect) which don't do anything security related all is ok. And you can just do (assuming applet with id="myapplet"
) myapplet.safeMethod();
directly in your javascript code.
The main problem with calling java methods, which do something normally restricted for applets, from javascript is that the calls seem to run in a different context in the JVM then the applet itself. Thus are treated as unprivileged code and you get the AccessControlException
. While e.g. like in my other answer, methods which are executed by the applet itself, get the right permissions and are executed.
Now if you read this LiveConnect Support in the New Java™ Plug-In Technology in section 2.8 Security Model of JavaScript-to-Java Calls SUN states
When a JavaScript-to-Java call is
made, the JavaScript code is modeled
as though it were coming from an
untrusted applet whose code origin is
the document base (i.e., the URL of
the directory containing the
document).
I read this as: If applet and javascript come from the same site than the javascript-to-java calls should run with the same permissions as the applet itself. Which in our case means with whatever rights we set in our grant
.
But this only works in Opera for me. FF and IE6 both throw AccessControlException
. But it might still work out for you in all browsers.
The following code has two methods userName2()
and userName()
. userName2()
WFM in all browsers. userName()
only works in Opera. Check by pushing the buttons on the html page.
As you can see userName2()
is not usable like this for a real usecase (can only be called once). But you can look into a solution someone else came up with when having a similar problem, and accordingly extend userName2()
Java Applet using LiveConnect
Additionally you might consider something I didn't try out. All calls from javascript-to-java do nothing security related just (if needed) pass in data and return immediately. Then the applet does the actual work (like in the link shown above). Then when finished the applet could fire a callback into the html page via the JSObject
(plugin.jar)
TestApp.java
import java.applet.Applet;
import java.awt.*;
import java.security.AccessControlException;
public class TestApp extends Applet {
Label output = new Label("What is the value of user.name?");
String userName;
Thread access = new Thread() {
@Override
public void run() {
try {
userName = System.getProperty("user.name");
} catch (AccessControlException e) {
userName = "Oops, failed in thread. No read permissions!";
}
}
};
public void init() {
setLayout(new BorderLayout());
add(BorderLayout.CENTER, output);
}
public String userName2() throws InterruptedException {
access.start();
access.join();
output.setText(userName);
return userName;
}
public String userName() {
String userName = "Oops, failed in liveconnect-context. No read permissions!";
try {
userName = System.getProperty("user.name");
} catch (AccessControlException e) {
e.printStackTrace();
}
output.setText(userName);
return userName;
}
}
test.html
<html><head><title>test</title></head><body>
<applet id="myapplet" code="TestApp" width="350px" height="80px"></applet><br>
<input type="button" value="liveconnect version" onclick="javascript:alert(myapplet.userName());"><br>
<input type="button" value="hacky thread version" onclick="javascript:alert(myapplet.userName2());">
</body></html>
Policy: .java.policy (created manually in C:/Documents and Settings/[USERNAME]/ Note the leading .
)
grant codeBase "http://[domain].xxx/-" {
permission java.util.PropertyPermission "user.name", "read";
};