úterý 29. července 2014

Applet in a spring web application


Another application our team is developing right now is a card access system. The system is quite complex, but the main idea is very simple. User is registered through the web application and receives a card. The card contains access information and when he comes to the door and uses the card, permissions are checked and he is either allowed to open the door or the access is denied.

The web application uses spring framework (3.2.4) and we use maven as the build tool. The main problem was to figure out how to communicate with the card through the web browser. Finally we found out that our only solution is to use java applets. But it’s much easier said than done.

In this article we’d like to cover all the steps needed to run java applet which uses clients’ system resources (such as a smart card reader), which may help you when you decide to use this deadly combination, too.


JNLP

Suppose, you have an applet built to a jar file called test-applet.jar (you can try to write some simple applet as an exercise).

The recommended way to launch applets on the webpage is by using the Java Network Launch Protocol (JNLP). Our test.jnlp file for this simple example looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<jnlp spec="1.0+" codebase="" href="">

  <information>

    <title>Test applet</title>
    <vendor>OKsystem s.r.o.</vendor>
    <offline-allowed/>
  </information>
  <resources>
    <!-- Application Resources -->
    <j2se version="1.6+"
                  href="http://java.sun.com/products/autodl/j2se" />
    <jar href="/SpringAppletTest/applet/test-applet.jar" main="true" />
  </resources>
  <security>
    <all-permissions/>
  </security>
  <applet-desc
        name="Test Applet"
        main-class="cz.oksystem.spring_applet_test.testapplet.TestApplet"
        width="800"
        height="550">
  </applet-desc>
  <update check="background"/>
</jnlp>

It contains basic information about the application, path to the .jar file, security information and the applet-desc element to run the applet.

Since we need our applet to work with a smart card reader, we also need the permissions to user’s computer resources. That’s why the all-permissions option is setup (the other possible option is sandbox).

JSP

The next step is to prepare the applet.jsp page which uses the jnlp file to run the applet:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="https://www.java.com/js/deployJava.js">             </script>   
    <title>Test JSP Page</title>
  </head>
  <body>
    <h1>Hello World!</h1>
       
    <div>
      <script>                   
        var attributes = {
          code: 'cz.oksystem.spring_applet_test.testapplet.TestApplet', archive: '/SpringAppletTest/applet/test-applet.jar', width: 800, height: 550};
          var parameters = {jnlp_href: '/SpringAppletTest/applet/test.jnlp', java_status_events: true};
                deployJava.runApplet(attributes, parameters, '1.7');                   
      </script>
    </div>
  </body>

</html>


The core functionality of the page lies between the script tags. First, we import the deployJava javascript from the java web page. Deploy-java.js (Deployment Toolkit script) contains useful functions that can be used to deploy applets in a web page, in this example the runApplet function. You pass to this function attributes and parameters containing information about the applet code base, archive which contains the compiled source and the jnlp location.

If you need to pass some additional parameters that the applet should use, just add them to the parameters object as the key-value pair and use the getParameter() function in your applet java code.


Manifest

When you create a JAR file, a default manifest file is created automatically (MANIFEST.MF). It simply contains the “header: value” pairs information about the file. To modify the manifest file, you must first prepare a text file containing the information you wish to add to the manifest.

Our sample manifest file manifest.txt contains following information:


Permissions: all-permissions
Codebase: *
Application-Name: test-applet
Trusted-Only: true
Trusted-Library: true
Caller-Allowable-Codebase: *
Application-Library-Allowable-Codebase: *


We will not give the full description of the file properties, because it’s not the aim of this article. You can find all the possible attributes with their detailed description in the oracle documentation page: 
http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/security/manifest.html


Maven manifest


As I have already mentioned in the beginning of this tutorial, we use maven as our build tool for this project. By default, maven archiver generates the manifest file for you. But in this particular situation we need to use our own manifest file that we have created in the previous step. This is done with the <manifestFile> configuration element by setting its value to the location of the manifest file. The content of this file will be merged with the entries generated by Maven Archiver. 
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
        <manifestFile>src/main/resources/META-INF/manifest.txt</manifestFile>
                </archive>
            </configuration> 
        </plugin>
    </plugins>
</build>


Spring-servlet.xml


The only 2 lines you have to add to your usual spring configuration file are the resources where the applet and javascript are located:

    <mvc:resources mapping="/applet/**" location="/applet/"/>   
    <mvc:resources mapping="/js/**" location="/js/"/>    


Complete project structure

Just for completeness, we attach also the structure of our applet and web application projects.





Signing the applet


At this point, when you build, deploy and run your web application, the following error is going to appear:





This happens because the applet you are using have to be signed. To self-sign the applet follow these 3 steps (don’t forget to use real certificates for production):
   
     1. keytool -genkey -keystore myKeyStore -alias testuser
     2. keytool -selfcert -keystore myKeyStore -alias testuser
     3. jarsigner -keystore myKeyStore test-applet.jar testuser

Because in this example the applet is self-signed you have to change the java settings to allow running also applications which are not signed by the trusted authority. To do this, go to Control panel -> Java -> Settings -> Security and change the security level to medium.



As the note under the security level slider says, “All Java applications will be allowed to run after presenting a security prompt”. I know it’s a very uncomfortable step, but when you realize that the applet has access to your system resources (in our case the card reader connected to the users’ computer), you also realize that this can be a perfect means to attack the clients computer. And that’s the main reason behind it.



After completing these steps you will be able to successfully deploy and run the application.

Futher notes

After completing these steps you should be able to run the applet in a spring web application. Similar steps may be used to make it run on the classic JavaEE platform.

Before we finish this tutorial, we want to point out 2 more issues you would most probably encounter while developing applets for the web applications.         

Applet cache

The first issue is the java applet cache. When developing java applets, you may come to a situation when you change some applet code, but when running it in the web browser, nothing changes even when you restart the browser to clear its cache (or clear it manually). The thing about this is a fact, that your browser is not responsible for caching java applets, java does it by itself. The reasons for caching applets are obvious. There is no need for downloading applets every time a user references them, which results also in their startup performance (but sometimes causes headaches to us, programmers). 

To clear java cache go to Control panel -> Java -> Settings -> Delete files. Load your web application again and your applet gets fully loaded again, including all of the changes.

Multiple resources in JNLP


The second issue is that sometimes you may need to use multiple resources in your JNLP file. In our case our card reading applet is using a common module with some cryptographic functions implemented there. The solution is to sign the module, build it and add it to the applet folder of your web page. Then reference this jar in resources element in the JNLP file.
...
  <resources>
    <!-- Application Resources -->
    <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" />
    <jar href="/SpringAppletTest/applet/test-applet.jar" main="true" />
    <jar href="/SpringAppletTest/applet/some-module.jar" />
  </resources>
...


We hope this tutorial helps you at least a bit and we wish you a happy coding.


1 komentář:

  1. Your blog article is really very impressive and well written. Thanks for sharing this wonderful description of web application with us and please keep updating with your thoughts.

    Vancouver home automation | Security vancouver | Best Security Vancouver

    OdpovědětVymazat