From the early days of the so-called Java sandbox to the robust, full-featured security architecture introduced with JDK 1.4, security has always been an essential component of the Java platform. In getting from there to here, the designers of the Java language have received plenty of community input on what does and does not a secure Java application (or enterprise environment) make; and they've also pulled a trick or two on their own.
Suffice it to say that with the introduction of the J2EE Web application security architecture, we're reaping the rewards of nearly 10 years of trial and error, and it shows. The J2EE security framework consists of three APIs: the Java Authentication and Authorization Service (JAAS), Java Secure Socket Extension (JSSE), and Java Cryptography (JCE). While JCE is an interesting and important API, it's not quite so central to our interests as the "big three" of secure Web application development: authentication, authorization, and transport. So in this month's column we'll focus on the JAAS and JSSE.
JAAS provides a flexible, declarative mechanism for authenticating users and verifying their ability to access secure resources. JSSE defines an all-Java mechanism for securing Web traffic over a Secure Socket Layer (SSL). By combining these two technologies, we can give our applications the ability to:
- Verify that a user is who he or she claims to be (authentication)
- Ensure that he or she is permitted access to the requested resource (authorization)
- Conduct the entire exchange over a secure network connection (transport)
Now, let's take a look at the individual components underlying all this functionality.
JAAS is built on a security architecture known as PAM (Pluggable Authentication Module). PAM's architecture is modular, which means it's designed to support the seamless exchange of one security protocol component for another by swapping out modules. Well-defined interfaces within the framework allow for the inclusion of multiple authentication technologies and authentication mechanisms without changing or interfering with any of the existing login services. The PAM architecture, and thus JAAS, is able to integrate a broad range of authentication technologies, including RSA, DCE, Kerberos, and S/Key. Additionally, the framework is compatible with smartcard-based authentication systems and LDAP authentication.
As is the case with so many of the Java 2 platform technologies, the JAAS API defines a clean abstraction between
application code and the physical implementation that will execute the business logic. The abstraction layer is what allows for the run-time substitution of login modules without recompiling existing application code. Specifically, applications write to the LoginContext API, while authentication technology providers write to the LoginModule interface. At run time, the LoginContext will read a configuration file to determine which login module(s)
should be used to authenticate users accessing a particular application.
The authentication scheme used by JAAS is grounded in two very important entities: principals and subjects. The person or service that is actually being authenticated is referred to as the subject. A principal is a unique entity such as the name of an individual or group, an account number, a social security number, or similar unique identifier. In order to uniquely identify a subject (which is a crucial component of authentication), one or more principals must be associated with that subject. Finally, a subject may own security-related attributes, known as credentials. A credential can be anything from simple password to a complex cryptographic key.
Applications begin the authentication process by instantiating a LoginContext object. The LoginContext queries a configuration to determine the authentication technology (or technologies) and
corresponding LoginModule(s) to be used in performing the authentication. A very simple LoginModule may prompt for and verify a username and password. A more advanced one might validate identity using an
existing operating-system login identity. Theoretically, a JAAS LoginModule could even be built to interface with a fingerprint reader or retina scanner.
Authentication is only half the battle in the Java security framework. Once a user's identity has been confirmed, his or her access rights must be examined. Only after the appropriate rights have been confirmed will the user be granted access to secured systems or resources.
To put this another way, once a user or service has been authenticated, a Subject object is created to represent the authenticated entity. This object is then passed by JAAS to any authorization components that have been established to guard access to sensitive systems or resources.
To determine authorization, the Java 2 Security Manager is supplied with the Subject and its Principals, as well as the privileged action the Subject wants to perform (reading/writing to the file system, database access, and so on.). The Security Manager consults a policy file which associates Principals and permissions. If one of the Subject's Principals has permission to perform the specified action,
then the Subject is authorized and the action is allowed; otherwise the action is denied and a SecurityException is thrown.
Thanks to JAAS we are able to identify users who access our system and restrict their access to the parts of the system they're authorized to use. While JAAS is a solid first step toward a secure Web application, application security isn't complete without secure transport.
At this point, we're still transmitting secure information (including authentication information) in plain text -- that is, HTTP, TCP/IP, FTP, and so on. So we need to make sure that, while in transit, the data isn't accessible to unauthorized parties. We also need to be sure, on arrival, that the data hasn't been modified during transit, whether intentionally or unintentionally. For both of these functions we can leverage the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols.
SSL and TLS are not Java-specific protocols, but rather network-layer protocols designed to maintain the integrity and privacy of traffic across a socket. The Java Secure Socket Extension (JSSE) enables secure Internet communications with SSL/TLS. It provides an application framework -- a Java version of the SSL and TLS protocols -- complete with the full range of functionality including data encryption, server authentication, message integrity, and more. Using JSSE, we can define secure socket connections between a client and server running any application protocol, including HTTP, TCP/IP, FTP, or even Telnet. From a data-encryption standpoint, JSSE encompasses many of the same concepts and algorithms as those in the JCE. More importantly though, it automatically applies them as necessary beneath a simple stream socket API.
To leverage the JSSE API, we only need to do a few simple things. First, we need to obtain a JSSE provider (see
Resources). Second, we need to obtain sockets from one of the JSSE socket factories, rather than directly from the java.net.Socket class. Client-side code retrieves sockets from the SSLSocketFactory, while server-side code retrieves sockets from the SSLServerSocketFactory. By retrieving
our sockets from these factories, we are able to leverage the framework provided by the JSSE provider, rather than simply creating standard, unsecured sockets as the java.net package allows us to do.
For more details on JSSE, see Resources.
The Java platform is known for its rock-solid application security. With each passing year the Java security framework becomes more flexible and robust, and the addition of JAAS and JSSE suggests that the legacy will continue.
This month, we took a quick peek at the technologies for securing a Java Web application. JAAS provides a modular mechanism for authenticating users and controlling access to resources. JSSE delivers a Java implementation of the SSL and TLS protocols supporting data integrity and privacy. Next month, we'll explore the brave new world of servlet filters. Until then, happy pathfinding!
- You'll find Brad Rubin's two-part Java
security tutorial, Part 1: Crypto basics and Part 2: Authentication and authorization (developerWorks, July 2002) an excellent start for learning more about the Java platform's Web application security architecture.
- In "Securing systems: A three-pronged solution for identifying users" (developerWorks, June 2001) Joseph Sinclair outlines the basic challenges of securing Web applications in enterprise systems, and provides a glimpse of how JAAS works to resolve them.
- Learn hands-on how to use JAAS to secure your enterprise applications, with Carlos Fonseca's "Extend JAAS for class instance-level authorization" (developerWorks, April 2002).
- In the tutorial "Using JSSE for secure socket communication" (developerWorks, April 2002) regular Java zone contributor Greg Travis walks you through the hardest and most important part of working with Java Secure Socket Extension -- creating and installing the JSSE encryption keys.
- In "Custom SSL for advanced JSSE developers" (developerWorks, September 2002) author Ian Parkinson shows you how to use JSSE to customize the properties of your Secure Socket Layer connections.
- See Vipin Samar and Charlie Lai's "Making Login Services Independent of Authentication Technologies" (java.sun.com) to learn more about the PAM framework.
- Jamie Jaworski's "Secure your sockets
with JSSE" (OnJava.com, May 2001) is an introduction to JSSE.
- The JSSE Reference Guide is an important resource for learning more about secure transport on the Java platform.
- You'll need a JSSE provider such as the IBMJSSE to get up and running with the Java Secure Socket Extension.
- You'll find hundreds of articles about every aspect of Java programming in the
developerWorks Java technology zone.

Kyle Gabhart is an independent consultant and subject matter expert with J2EE, XML, and Web services technologies. Kyle is a popular public speaker, recognized for his enthusiasm and dynamic analysis and presentation of emerging technologies. Kyle can be reached at kyle@gabhart.com.