Search code examples
javasecurityjava-web-startpolicy

Java (8) Webstart: avoiding security popups


I'm currently working on a somewhat older JavaFX application that runs under JRE 1.8.0.77. It is ran within a closed network, without an internet connection. This application is deployed through Webstart to several hundreds of machines and we want to avoid having users click through a security popup since machines are often re-imaged.

The jnlp has the tag:

<security>
   <all-permissions/>
</security>

Oracle lists two main ways of achieving this, apart from ticking the "don't show me again" box:

  1. The certificate can be manually imported into the JRE trusted certificate store.
  2. Grant AllPermissions in the Java policy file located at ${user.home}/.java.policy, or point to any Java policy file which has AllPermissions in the $(JRE_HOME)/lib/security/java.security file.

Source

At this point I've tried both methods but I am facing the following issues:

Granting AllPermissions

This is my preferred way of getting it done, since the applications are ran in a closed network and have less of a security risk. However I tried to add the following text:

grant {
     permission java.security.AllPermission;
};

to several locations, including:

  • $USER_HOME/.java.policy
  • $JAVA_HOME/jre/lib/security/java.policy
  • $JAVA_HOME/jre/lib/security/javaws.policy (using -verbose whilst running webstart lists this as "-Djava.security.policy")
  • I've even made a custom policy.file, posted it under the user home directory and pointed to it through "deployment.system.security.policy" as specified in here.

It seems as though these policies do have effect, because when I remove permissions from, for example, .java.policy webstart will refuse to run as a whole.

But every time I launch webstart, given a url where the jnlp resides, it will show the security pop-up.

Import the certificate

This seems like a proper way to do it, however the first thing I noticed is that when you allow a certificate through the manual popup it is placed in a keystore that resides in $USER_HOME/.java/deployment/security and not in $USER_HOME/.keystore OR $JAVA_HOME/jre/lib/security.

Using the "deployment.user.security.trusted.certs" as mentioned here I can have webstart use a keystore that I provide. (As an extra note, when webstart creates its own keystore, the password is "". This information, apparently, was hard to find)

The manually approved certificate then gains the following alias, which seems mandatory for it to be identified correctly in subsequent runs:

deploymentusercert$tsflag$loc=http//webserver.com:80##jnlp:http//webserver.com:80##from:http//webserver.com:80java.util.random@530ea09d

Where webserver.com is the URL of the jnlp's location. If I don't exactly have this alias mentioned alongside the certificate it seems to not get recognized in subsequent runs and shows another security popup. Exporting and importing the certificate manually does not add this alias and thus it is not recognized.

I could use this exact alias and distribute it on the user machines, however these user machines are distributed along several locations which each host their own jnlp file. This means there is no generic alias I could use.

In conclusion

It seems that the only way I could avoid having this security popup is to manually approve the certificate and then distribute that exact keystore generated by webstart to the user machines. Then I have to repeat this proces for each individual location that gets its jnlp from somewhere else.

I hope someone knows a different solution or has found an error in my story, since it seems like we are going to have to instruct users to click the box. Thanks in advance for any tips!


Solution

  • This blog describes the solution best: http://symplik.blogspot.com/2013/11/get-rid-of-java-applet-warning-when_3.html

    For webstart to recognize and use the certificate it has to have at least the following alias within the keystore:

    deploymentusercert$tsflag
    

    It seems like having the random number and URL was not necessary.