Developing an SSL-Enabled Web Application With Sun Java System Application Server 8.1

   
By Carol Zhang and Phua Choon Hong, September 1, 2005  

With the growing need for information security in today's digital systems, SSL has become the universally accepted method for setting up authenticated and encrypted communication between clients and servers. This article will discuss how to use the Sun Java System Application Server 8.1 software (hereafter referred to as Application Server) to build SSL-enabled web applications and how to implement SSL client authentication in the Java 2 Platform, Enterprise Edition (J2EE) 1.4 security realm.

Introduction to SSL

In the TCP/IP protocol stack, SSL protocol sits between TCP/IP and the higher application-level protocols such as HTTP or SMTP. SSL implementation calls TCP/IP on behalf of the application, and it allows the SSL-enabled server and the SSL-enabled client to authenticate to each other and establish the encrypted connection between the two endpoints. This article addresses three fundamental concerns about SSL-based communication over the Internet:

  • SSL server authentication
  • SSL client authentication
  • Encryption of the SSL connection

SSL server authentication allows a user to confirm a server's identity. SSL-enabled client software can use standard techniques of public-key cryptography to check that a server's certificate and public ID are valid and have been issued by a certificate authority (CA) listed in the client's list of trusted CAs. This confirmation might be important if the user, for example, will be sending a credit card number over the network and wants to check the receiving server's identity.

SSL client authentication allows a server to confirm a user's identity. Using the same techniques as those for server authentication, an SSL-enabled server can check that a client's certificate and public ID are valid and have been issued by a CA in the server's list of trusted CAs. This confirmation might be important if the server, for example, is a bank that will be sending confidential financial information to a customer and wants to check the recipient's identity.

An encrypted SSL connection requires all information sent between a client and a server to be encrypted by the sending software and decrypted by the receiving software, thus providing a high degree of confidentiality. Confidentiality is important for both parties in any private transaction. In addition, all data sent over an encrypted SSL connection is protected with a mechanism to detect tampering -- that is, to determine automatically whether the data has been altered in transit.

The execution of the SSL protocol will go through several phases: the SSL handshake, the server authentication, and the optional client authentication phase. Only then is the encrypted communication channel established. This article will not detail the SSL protocol but will guide you in building an SSL-enabled web application in the Application Server.

Enable SSL in the Application Server

Version 8.1 of the Application Server is the latest J2EE 1.4-compatible release of the Sun Java System Application Server. It consists of three editions: the Platform Edition for free download, a full J2EE 1.4 server with integrated web service security and JavaServer Faces technology; the Standard Edition, featuring remote, secure, multimachine management; and the Enterprise Edition, for the most demanding operational environments, incorporating the Standard Edition's capabilities.

To enable SSL, we will first learn how to manage certificate files, which store the digital certificates for all SSL participants including the server, the client, and the CA. The SSL engine will retrieve these digital certificates from the store and use them for authenticating and encrypting messages based on Public-Key Infrastructure (PKI) technology.

It's worth noting that the tools used for managing certificate files are different in the Application Server's three editions. The Platform Edition uses the Java Secure Socket Extension (JSSE) format and leverages the key tools shipped with the JDK for key-certificate management. The Standard Edition and Enterprise Edition, however, use Network Security Services (NSS) tools for storage and management. This article will use the tools in the Standard Edition as an example to depict a more typical scenario.

Note: JSSE is a set of Java packages that enable secure Internet communications. It implements a Java technology version of SSL and Transport Layer Security (TLS) protocols. It includes functionality for data encryption, server authentication, message integrity, and optional client authentication. By comparison, NSS provides a complete open source implementation of the crypto libraries used by Netscape, Sun, and other companies in a variety of products, including the Application Server. This article covers only the NSS tools for the Standard Edition and Enterprise Edition.

Before continuing, let's review some of this article's directory variable conventions:

  • The phrase as_install_dir   refers to the directory in which the Application Server is installed. Default to /opt/sun/appserver.
  • The phrase domain_dir   refers to the directory in which the domain is installed. Default to /var/opt/appserver/domains.
Certificate Files and Tools

By default, the Application Server stores the certificate information in two NSS-format files in the domain_dir /domain_name/config directory:

  • KeyStore file. Named key3.db by default, this file contains the Application Server's digital certificate, including its private key.
  • Trust-store file. Named cert8.db by default, this file contains the Application Server's trusted certificates, including public keys for other entities. Trusted certificates generally include those of CAs.
Certificate Database Tool: Certutil

The Certutil tool is used to set up and work with NSS digital certificates. This certificate database tool is a command-line utility that can create and modify the NSS-format files of cert8.db (Trust-store) and key3.db (KeyStore) database files. It can also list, generate, modify, or delete certificates within the cert8.db file, create or change the password, generate new public and private key pairs, display the contents of the key database, or delete key pairs within the key3.db file.

To verify the default-generated KeyStore and Trust-store files, use the following command to list the entries in the certificate files:

-bash- 3.00#  
                   as_install_dir/lib/certutil -L -d  
                   domain_dir/domain1/config

                

The following message will be printed out with the default installation of the Application Server:

verisignc1g1                                                 T,c,c
verisignc1g2                                                 T,c,c
...
...
s1as                                                         u,u,u

The text on the output's left is the certificate's unique nickname, and the text on the right is a set of three capability identifiers for the CA, SSL, email and object signing, in that order. The most commonly used identifiers are the following:

p   Valid peer
P   Trusted peer (implies p)
c   Valid CA
T   Trusted CA to issue client certs (implies c)
C   Trusted CA to issue server certs (for ssl only) (implies c)
u   User cert

Note that the installation of the Application Server generates a digital certificate in NSS format, s1as, that is suitable for internal testing. We will talk about this in the next section and see how this sample digital certificate helps the internal testing. For production purposes, you may wish to add this certificate to the KeyStore and Trust-store files. Make sure to choose the correct certificate identifier for the newly added certificate. We will illustrate how to use the Certutil tool to manage the files. 

First Try

In this part, we will make a simple configuration in the Admin Console to enable SSL for your server by using the preconfigured server certificate.

After the application server startup, bring your browser up to the Admin Console. Go to Configurations - > server-config -> HTTP Service -> HTTP Listeners. Click New to create a new HTTP listener with security enabled. The new listener is named HTTP-listener-3, and the listener port is set to 8282. Type the network address and select the virtual server name. The diagram illustrates the listener's configuration.

Figure 1: Configuring the HTTP Listener


Access https:// server_name.domain_name:port_number/index.html in another browser. For example, if you use Mozilla in the Admin Console, then use Internet Explorer to access this page. Another option is to restart your browser to clear the SSL status. The Security Alert window will open and ask you whether to accept the certificate. If you accept, the Welcome page shows up. In the simple try, if you attempt to view the SSL detail in the Security Alert window, the s1as server certificate will be displayed.

We will now add more functions. After this section, we will learn how to deal with certificates in the real application.

Create an SSL Certificate Authority (CA)

You create a CA by using the Certutil tool. Following is the command to create the self-signed CA certificate and add it into the Application Server's certificate database:

-bash-3.00# certutil -S -x -1 -2 -5 -m 100 -t "TCu,Cu,Cu" -s \
"cn=testCA,o=Sun,ou=sun.com, C=CN" -n SSLTestCA -v 6 -d  \
                    domain_dir/domain1/config
                

After issuing the command, you are required to type randomly on the keyboard until the progress meter is full to create the random seed for key creation. After the key is created, you are prompted to select from the following Options menu:

0 - Digital Signature
1 - Non-repudiation
2 - Key encipherment
3 - Data encipherment
4 - Key agreement
5 - Cert signing key
6 - CRL signing key
Other to finish 

One by one, select options 0, 1, 5, 6 and 9, and type y when the program asks whether this is a critical extension. After that, you will be prompted to select from other option menus, where you should choose 5, 6, 9 for SSL CA and S/MIME CA.

Once you complete this command, you will find that SSLTestCA CTu,Cu,Cu are listed in the entries of the certificate files.

In a production environment, you are more likely to import the existing CA certificate to the certificate database than to generate your own keys in self-signed form. For example, to import the certificate from a file named rootCA.cer, you would execute this command:

-bash-3.00#  
                   as_install_dir/lib/certutil -A -n rootCA -t "TCu,Cu,Tuw" -i \
rootCA.cer -d  
                   domain_dir/domain1/config
                

Create a Server Certificate

Create and add the server certificate, which is signed by the newly created CA, SSLTestCA:

-bash-3.00#  
                   as_install_dir
                   /lib/
                   certutil -S -c SSLTestCA -m 101 -t \ "Pu,Pu,Pu" -s "cn=sanjose,ou=sun.com,C=CN" -n MyServerCert -v 12 -d \                       domain_dir/domain1/config                   
                

Enable Client Certification for the HTTP Listener

In the Admin Console, go to Configurations -> server-config -> HTTP Service -> HTTP Listeners. Select HTTP-listener-3, which you configured in the previous step. Check Enable Client Certificate; type MyServerCert as the certificate nickname; and enable SSL3, TLS, and Ciphers Suites. Save your configurations. This will enable the client certification for the HTTP listener.

Create the Client Certificate

Execute the following command to generate the client certificate:

-bash-3.00#  
                   as_install_dir/lib/certutil -S -c SSLTestCA -m 160 -t \
"Pu,Pu,Pu" -s "cn=carol, ou=sun.com, C=CN" -n ClientCert -v 12 -d \
                    domain_dir/domain1/config
                

Export the client certificate to a file:

-bash-3.00#  
                   as_install_dir/lib/pk12util -o ClientCert.p12 -n ClientCert -d \
                    domain_dir/domain1/config
                

In each of the above steps, you will be prompted for the master password to the certificate database. Enter the master password with which you configured the Application Server.

Import the Client Certificate to the Browser

Open your browser and import ClientCert.p12 to your certificate store. Optionally, you can import the CA's certificate to your browser to avoid the Security Alert window. Please refer to Mozilla help or Microsoft IE help for instructions on how to import a certificate.

Combine SSL With J2EE Authentication

In the previous section, we discussed how to configure SSL in the Application Server by setting up the encrypted channel for the message transfer in the transportation level. How does the J2EE application, which runs above the transportation level, make use of the client credentials to do the application-level authentication? We will reveal the implementation details in this section.

There are two types of J2EE security implementations: container authentication and custom authentication. We will review the concepts of the two authentication implementations and examine how SSL fits into the two schemes.

Container Authentication

A container is an environment in which an application runs. Container authentication is the process of telling the container the identity of the user making the current request. The J2EE specification defines four mechanisms to authenticate users: HTTP basic authentication, HTTP digest authentication, HTTPS client authentication, and HTTP form-based authentication.

Version 8.1 of the Application Server supports three types of authentication:

  • HTTP(S) basic authentication: When a browser requests any of the protected resources, the server asks for a username and password by using the client browser's pop-up login dialog box. If the user enters a valid username and password, the server sends the resource.
  • HTTP(S) form-based authentication:This mechanism is similar to basic authentication. However, instead of using the browser's pop-up dialog box, it captures the username and password from the HTTP form in the custom login and error pages.

In both of these methods, you have the option of enabling the encryption of user credentials by using SSL.

  • SSL client authentication: The server authenticates the client by using the public-key certificate. It is the most secure one among the several types of authentication methods, and all the common browsers support it.

As we have seen, the user credentials passed between client and server are different in the three authentication methods, that is, where SSL technology plays different roles.

We will focus on the SSL client authentication implementation, in which the public-key certificate is used as a user credential. Generally speaking, security in the J2EE application can be enforced by using either a declarative approach or a programmatic approach. When using the declarative approach, the application developer defines an application's security constraints outside the application code. These declaratives are made in deployment descriptors ( web.xml: ejb-jar.xml), and container runtime environments guarantee their enforcement.

To configure SSL client authentication, you define roles in the J2EE deployment descriptor file, web.xml, and the corresponding role mappings between the client certificate Distinguish Name (DN) and roles in the Application Server deployment descriptor file, sun-application.xml (or sun-web.xml for individually deployed web modules).

Here is the code in web.xml:

<security-constraint>
      <web-resource-collection>
        <web-resource-name>clientcert security test</web-resource-name>
        <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
         <role-name>staffmember</role-name>
      </auth-constraint>
  </security-constraint> 
     <login-config> 
      <auth-method>CLIENT-CERT</auth-method> 
      <realm-name>certification</realm-name> 
  </login-config>

The sample deployment contains the following security configuration:

  • The application restricts access to a URL that begins with the pattern /* (the url-pattern).
  • Only a user belonging to the staffmember role can access these resources (the role-name).
  • Remote users are authenticated using the Client-Cert authentication method.

Here is the code in sun-application.xml:

<security-role-mapping>
     <role-name>staffmember</role-name>
         <principal-name>cn=carol, ou=sun.com, C=CN</principal-name>
             <group-name>staff</group-name>
              </security-role-mapping>

The declared principal name and group name belong to the role staffmember. The principal name is the certificate DN, which uniquely identifies the client.

Download the source code ClientCertApp.ear. Then cut and paste the principal name that you used in your configuration into sun-application.xml. Deploy this application and access the page https:// server_name.domain_name:port_number/<web-context-root>/index.jsp .

As we discussed earlier, the client certification-based container authentication in the Application Server provides only rudimentary principal- and role-based authentication. When you want more flexibility for the authentication, you may find custom authentication a better choice.

Custom Authentication

The most common implementation of custom authentication is that user credentials are retrieved from a form submission and then compared against a persistent store, usually a database or LDAP. The user is either allowed or denied access to the system. If the user is allowed access, an object is usually placed into the session that identifies the user who has access to the application. After that, the business logic related to authorization can be implemented and enforced based on the established user identity and predefined rules.

You can place this example code into an authentication servlet filter:

User user = (User) request.getSession.getAttribute("com.test.User");
If (user == null) {
  X509Certificate ax509certificate[] = 
      (X509Certificate[])request.getAttribute
("javax.servlet.request.X509Certificate");
  String userDN = ax509certificate[0].getSubjectDN().toString();
  user = CustomAuthentication.login(userDN);
  if (user != null && user.isValid()) {
    request.getSession().setAttribute("com.test.User", user);
  } 
}

The code above allows the application to check the session for the User object on subsequent requests to determine whether a user has logged in and has access to the application.

The following code is an example of an implementation of the CustomAuthentication object used in the servlet code above. In addition, this implementation uses JDBC to verify the user's credentials with a relational database.

import ...
public class CustomAuthenticator {
    public static final String SQL = "select * from user where userDN = ?";
    public static User login(String userDN)
    throws AuthenticationException {
        User user = null;
        Connection connection = getConnection();
        PreparedStatement statement = null;
        ResultSet rs = null;

        try {
            statement = connection.prepareStatement(SQL);
            statement.setString(0, userDN);
            rs = statement.executeQuery();
            if (rs.next()) {
                user = new User(userDN);
            }
        } 
        catch (SQLException e) {
            closeObjects(connection, statement, rs);
            throw new AuthenticationException("Unable to verify user");
        }
        return user;
    }
    ...
}

You can download a simple file, GetCert.zip, that demonstrates how to retrieve the client certification from an HTTP request.

Another solution implements the standard Java Authentication and Authorization Service (JAAS) interfaces. Such implementations call the custom authenticator shown above rather than calling a container authenticator. The code snippet above could easily be placed in a JAAS login module instead of in a servlet to accomplish this type of custom authentication.

A Word About the SSL Accelerator

As many people know, using SSL can slow the application's performance significantly because encrypting and decrypting messages are CPU-intensive operations. The common solution is to leverage some dedicated hardware -- the SSL accelerator or its equivalents -- to do the SSL-related computing. This device sits between the client browser and the web server, establishes the SSL connection with the client, and does inbound and outbound message encryption and decryption. But note that the SSL connection is terminated at the SSL accelerator end and that the protocol between the SSL accelerator and the web server is HTTP.

However, if the client certificate is required as the user credential to access the web application, we need to check whether the SSL accelerator has the capability to provide the client certificate or the client DN to the back-end web server in the HTTP request.

SSL's Limitations

SSL is widely used as the security schema in web applications. However, despite its popularity, it has some limitations.

First, SSL is designed to provide point-to-point security, which falls short for some scenarios in which multiple intermediary nodes may exist between the two endpoints while end-to-end security is needed. For example, in a typical web services environment, in which XML-based business documents route through multiple intermediary nodes, those intermediary nodes can have difficulty participating in security operations in an integrated fashion.

Second, SSL secures communication at the transport level rather than at the application or message level. As a result, messages are protected only in transmission over the network, but sensitive data used in the application or stored on the user's hard disk is not generally protected if that system lacks an additional encryption technology.

Due to these limitations, SSL may not be suitable in every situation. Other technologies are being developed at the application level to address specific security concerns. For example, XML-based security schema have been developed in recent years to provide comprehensive and unified security schemas for web services.

Summary

SSL is a popular security technology, offering mutual authentication and message encryption in server-client communications. This article provides the steps to enable SSL in your web application and to implement SSL-enabled J2EE security in Application Server 8.1. The article also discusses SSL's limitations to help developers better position SSL technology.

For More Information
Acknowledgments

I am indebted to the following people for their help with this article:

  • Mark Basler from the Product Team for his review and valuable input
  • Amanda Waite, Wang Yu, and Paul Huang for their advice, comments, and suggestions
  • Steve Essery for his valuable write-up
  • Geneviève Duboscq and Jill Welch for their editorial assistance
About the Authors

Carol Zhang is a member of the technical staff in the Market Development Engineering department at Sun. With seven years of experience in software development and technical consulting, Carol provides technical consultation to Sun's partner software vendors in China.

Phua Choon Hong is a member of the technical staff in Remote Software Delivery, supporting Sun's customers in application server issues.

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.