HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML

Most developers build J2EE applications using their own security mechanism. This causes problems when other applications are introduced, because more logons have to be remembered and users have to physically log on multiple times to use different Web applications. A single sign-on allows a user to logon once and have transparent access to all the applications within a domain.

In Part 1 we explain what a single sign-on is and how it works, enabling you to implement a single sign-on solution. In Part 2, we'll implement a single sign-on solution for standalone and Web-based applications.

Single sign-on (SSO) in client and Web applications share common behavior but also differ due to their content delivery mechanisms. In Web applications, single sign-on allows a user to log in once to a centralized server and transparently access multiple sites or Web applications without having to log in to each Web application. Single sign-on for a standalone application allows a single application to obtain services from multiple servers by reusing a set of credentials through the Java Authorization and Authentication Service (JAAS).

Single Sign-on for Web Applications
Single sign-on in Web applications uses secure cookies, redirection, encryption, life-cycle management servlets, member servers, and a login server.

Secure cookies are Web browser cookies that can't be copied, read, or sniffed. Normal cookies are usually written to a cookie file. This is inherently insecure because an attacker could copy this cookie information to another machine where he or she could masquerade as the victim. In-memory cookies are not persistently written to a cookies file but to the browser's memory space. As a result, in-memory cookies protect users from a cookie file attack.

Cookies that can't be read have their payload encrypted. Although a cookie payload is encrypted, an attacker could sniff a network segment to obtain the cookies with encrypted payloads and initiate a replay attack. A hacker uses a replay attack by sniffing for cookies set after a user logs in. Although the hacker can't read the information in the cookies, he or she can use the cookies to masquerade as the victim.

To protect against sniffing attacks use the HTTPS protocol when transferring login server cookies to and from the client. This ensures that any information sniffed will be useless. The login server uses secure cookies to keep track of whether or not a user is logged in.

Redirection is the process by which users are transparently sent from member servers to login servers and vice versa. Redirection can be accomplished with META tags or JavaScript.

Encryption is the process by which clear text is transferred into cipher (encrypted) text. Symmetric and asymmetric encryption are two forms of encryption. Symmetric encryption utilizes a single key to encrypt and decrypt information. Asymmetric encryption utilizes a key pair where anything encrypted by one key can only be decrypted by the other. It's possible to use either method with SSO; however, symmetric key encryption allows all member servers participating in the login domain to share secure information using a single key, which is easier to manage and requires less maintenance when replaced.

The life-cycle management servlets allow the login server and member servers to notify each other of login, registration, and logout events. Each member server and login server has an LCM servlet that serves as the sole communication point between a member server and a login server. LCM servlets are accessible only through SSL. The LCM servlets have slightly different roles depending on whether they're located on member servers or the login server. The LCM servlet on the login server receives requests from member servers to login, register, or logout users. After the login server logs in, registers, or logs out a user, it notifies member servers through their corresponding LCM servlet via a redirect.

Member servers delegate the authentication of users to the login server. They represent the different applications that need to be integrated under an SSO domain.

The login server is the central authentication service and is responsible for major events in a Web site-user's life cycle. The major events include registration, login (authentication), and logout. When a user needs to register and set up an account with any of the member servers, they're redirected to the login server.

The login server presents a common registration page that encompasses all information required by participating member servers. The login server stores this registration information, stores the member server details, sets a cookie, and redirects the user back to the LCM servlet of the member server that originated the request. All the encrypted registration information is sent back as well so the member server can store this information locally. The member server decrypts the information, then logs the user in and establishes its own session management mechanism.

A similar process occurs when a user logs in. First the member server notices that a user has not logged in. The member server redirects the user to the LCM servlet on the login server with a login directive. The login server notices that the user has not logged in and presents a customized login page for that particular member server. Once authenticated, the login server stores the member server details, sets a cookie, and redirects the user back to the LCM servlet of the member server that originated the request. Encrypted user information is passed back to the member server, which then decrypts the information, logs the user in, and establishes its own session management mechanism.

When a user clicks a link to another member server (where the user has not been authenticated), that member ser- ver notices that the user has not been authenticated. The member server redirects the user to the LCM servlet on the login server with a login directive. This time the login server notices the login cookie, stores the member server details, and redirects the user back to the LCM servlet on the member server that originally redirected the user to the login server. Encrypted user information is passed back to the member ser- ver, which then decrypts the information, logs the user in, and establishes its own session management mechanism. This process is repeated for every other member server when accessing a particular member server for the first time after logging in to the login server.

When a user logs out of the application, none of the member applications should be left open. The user initiates a logout by clicking a logout icon. This redirects them to the login server's LCM servlet with a logout directive. The login server has stored information about which member servers the user has logged into and redirects users to each of the member server's LCM servlets with a logout directive. Again encrypted user information is passed to the member servers. Each member server redirects the client back to the login server so it can record the successful logout of a particular member server. It redirects the user to the next member server he or she needs to log out of; this process continues until there are no member servers left. At this point the login server returns a logout success page.

Now that you've gained a strong understanding of single sign-on for Web applications, let's look at how single sign-on is implemented for standalone applications.

Single Sign-on for Standalone Applications
Single sign-on for standalone applications uses JAAS, General Security Service API (GSS), and a centralized authentication resource. JAAS provides the authentication and authorization mechanism. The GSS API provides mutual authentication, confidentiality, and integrity of individual messages passed between a sender and a receiver over a stream. A centralized authentication resource provides ease of maintenance and a unified API for integrating Java applications with single sign-on. There are many resources on the Net that provide in-depth information on these technologies. The following is a brief introduction.

Java Authentication and Authorization Service
As the name implies JAAS is a framework that allows Java programs to authenticate and authorize users. Authentication revolves around the following classes: Subject, Principal, LoginModule, CallbackHandler, and LoginContext.

A Subject represents a client to an authentication service, and can be people or other applications. After it's authenticated it has a number of Principals associated with it.

Principals represent the unique identifiers for an authentication domain. An example of a principal in a database could be your employee ID. A principal in Kerberos is a string that looks like "[email protected]". An IRS principal would probably be your social security number. LoginModules physically assign Principals to Subjects.

LoginModules abstract the general authentication mechanism of your application in a pluggable fashion. A simple example of a LoginModule would be one that authenticated your credentials using a database. A more complex LoginModule might require biometrics for authentication using a temperature and heart rate-sensitive fingerprint scanner. The actual interface to the authenticating hardware uses CallbackHandlers.

CallbackHandlers are responsible for interfacing with the authentication hardware to obtain the actual proof that a user is who he or she claims to be. A NameCallback and PasswordCallback have already been implemented to enable you to get the username and password from a user. Other CallbackHandlers can be written to interface with SmartCard readers. An application interfaces with JAAS through a LoginContext.

The LoginContext is the authenticating application's interface into JAAS. It's responsible for initiating the login (using the LoginContext.login method) and retrieving the authenticated Subject (using the LoginContext.getSubject method). The LoginContext's constructor takes two arguments. The first names a JAAS-specific policy file to select one or more LoginModules used for authentication. The second parameter identifies a CallbackHandler to retrieve authenticating credentials from the user. After a user has been authenticated, JAAS binds Principals to the user's Subject, which is used by JAAS Authorization.

JAAS Authorization controls user actions based upon the Principal objects associated with the authenticated user's Subject and policy file permissions. There are three main components to JAAS Authorization: Subject class, PrivilegedAction class, and a Java policy file.

JAAS Authorization uses the Subject.doAs( Subject, PrivilegedAction) and Subject.doAsPrivileged( Subject, PrivilegedAction, AccessControllerContext ) methods to control code (in the run method of the PrivilegedAction) that has permissions associated with it. Subject.doAs( ) associates the specified Subject with the current Thread's AccessControlContext. Subject.doAsPrivileged( ) associates the specified Subject with an AccessControlContext passed into the method. The code that must abide by policy file rules is encapsulated within the run () method of the PrivilegedAction interface, which has one method (see Listing 1).

JAAS Authorization has extended the standard Java 2 policy file by adding a Principal section after the signedBy and codebase sections. For example:

grant signedBy "abe",codebase "file:./someFile.jar",
Principal com.infogain.security.principal.InfogainPrincipal "joek" {
permission java.util.PropertyPermission "java.home", "read";
Before JAAS Java could only restrict code actions based on the signer of the code and where the code existed on the file system or network. With JAAS you can restrict a specific user's actions. In the above grant block we're saying that the only principal allowed to read the "java.home" system property is a Subject that has an InfogainPrincipal storing the value "joek". Although some might deem JAAS sufficient for a single sign-on, I feel it's necessary to add additional security measures for data transferred between the client and server.

General Security Service API
The General Security Service API provides a way of securely transferring messages between a client and server utilizing a single sign-on infrastructure. It's an implementation of RFC 2743 and has its own RFC in 2853. According to RFC 2853, "The GSS-API allows a caller application to authenticate a principal identity, to delegate rights to a peer, and to apply security services such as confidentiality and integrity on a per-message basis." The two supported centralized security services are Simple Public Key Mechanism (SPKM) and Kerberos Version 5. In this article we focus on Kerberos V5.

Centralized Authentication Resource
All applications delegate authentication responsibility to Kerberos. Kerberos is a single sign-on service that acts as a mediator when users and services want to authenticate themselves to each other. It was developed at MIT based on work by Needham and Schroeder. It's available on almost all platforms and has been incorporated into Windows 2000/XP. Keberos provides a single management interface for user/password management. Kerberos also provides the underlying security services for mutual authentication, confidentiality, and integrity used by the GSS API.

When using JAAS and Kerberos, single sign-on becomes transparent to the application user. To utilize single sign-on, users start their applications, authenticate to JAAS, and access any distributed applications running on the network.

In Part 2 we'll show how to implement single sign-on using code examples.

Author Bios
Abraham Kang is an integration architect for Infogain's Enterprise Integration Solutions group. His focus is J2EE, security, and enterprise application integration. Abraham has been developing in Java for five years. [email protected]

Donald Levy is the director of alumni relations and development information systems at Stanford University. Donald has a BS from MIT and an MS from Columbia University. [email protected]


Listing 1
   public Object run ();

        Here is an example of a class implementing PrivilegedAction:

   public class TestAction implements java.security.PrivilegedAction {

      public Object run () {
                        System.out.println("You are supposed to do some controlled " +
                "action like getting a system property (user.home = " +
                                System.getProperty("user.home") + ")";



All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.