I have designed an Applet to take a screenshot and save it on the users computer using the java.awt.Robot class. I need to embedd this applet into an html page (using the object tag) so that when the user clicks a button on the webpage the screenshot is taken.
The applet itself works fine, i’ve tested it by adding a temporary main method to it and running it on my local machine as a regular java app.
Where I’m having difficulty is setting up permissions to allow it to run from its embedded location. Obviously the robot class is somewhat hazardous so an AWTPermission needs to be established and the applet itself needs to be signed.
I followed through the tutorial at http://download.oracle.com/javase/tutorial/security/toolsign/index.html and succeeded in creating a signed .jar file and then a policy file that allowed the demo application in that tutorial to run. Where I am now running into issues is how to reconcile what I’ve learned with the situation my applet will be used in.
My target audience comprises around 100 machines and I need it to be executable on all of them. I have packed my java .class file into a .jar and signed it using keytool and jarsigner. I then uploaded the .jar and .cer files to the server directory where the pages in question are hosted.
However: When I then used policytool to create a new policy file on one of the machines to test the setup I am still unable to execute the applet from the HTML. I get Java.Security.AccessControlException Acess Denied java.awt.AWTPermission createRobot errors.
I rather suspect its the policy step that is going awry, so I’ll outline the steps I took:
I download the certificate to the local machine and generate a keystore from it, I launch ‘policytool’ from this directory through the commandline
I add the directory on the local machine where the keystore generated from and my certificate is located.
I then hit the add policy button and enter the SignedBy alias
Then Add Permissions and select AWTPermission
Targets name I select createRobot
The function field I have been leaving blank as I cant think what would apply here
Signed By in this window is also left blank
I then hit ‘OK’ and ‘Done’ and get a warning that there is no public key for the alias I’ve entered in the first step. I do a ‘save as’ and save my policyfile to the same directory as I put the certificate and the keystore generated from it.
This is not allowing me to run the applet from the webpage however and my limited understanding of this aspect of programming offers no clues as to what has gone wrong.
Ideas, thoughts, observations? If I havent explicitly mentioned something then I havent done it. My biggest suspect is the warning I recieve but I cant seem to find why its appearing
EDIT: Forgot to mention a step. I manually added to my jre\lib\security\java.security file the line ‘policy.url.3=file:/C:/Testing/debugpolicy’ since thats the path and policy filename I created during the above steps. I also just now managed to remove the warning I mentioned earlier, I’d been mixing up my alias’ and gave the alias for the private keystore rather than the public one during policyfile creation, however I still encounter the same problems
If an applet is correctly signed, no policy file is required, nor is it required to separately upload any certificate. A correctly signed applet will prompt the user for permission when the applet is visited, before it loads. Does the prompt appear?
Here is a small demo. I wrote that demonstrates Defensive loading of trusted applets. That is the security prompt I am referring to.
If the applet is both digitally signed by the developer and trusted by the end user, it should be able to take a screen-shot.
There is one other thing you might try if the applet is trusted, just as an experiment (1). Early in the applet
init(), callSystem.setSecurityManager(null). That will both test if the applet has trust, and wipe away the last remnants of the ‘trusted’ security manager given to applets.And in the case that works, and it makes the screen capture successful, it suggests either a bug or Oracle changed their mind about the defaults of what a trusted applet could do.
1) Don’t do this in a real world or production environment. To quote Tom Hawtin:
Edit 1:
Here is the source of the simple applet used in that demo. For some reason when I originally uploaded it, I decided the source was not relevant. OTOH 3 people have now asked to see the source, for one reason or another. When I get a round tuit I’ll upload the source to my site. In the mean time, I’ll put it here.