US Department of Energy signs on to J2EE

Create a secure single sign-on Web service for multiple n-tier Web applications

1 2 Page 2
Page 2 of 2

How the architecture works from a user's perspective

The SSO application is really a Web service to other Web applications, although this might not be apparent from a user's perspective. For users, the ideal situation would follow these steps:

  1. A user (respondent, contractor, or staff member) goes to the EIA-wide sign-on page
  2. The page asks the user to provide a username and credentials
  3. If the credentials are verified, the user sees a list of Web applications (e.g., surveys) that he has permission to access
  4. If a respondent or internal user tries to access a Web application without authentication, he is redirected to the EIA-wide sign-on page
  5. When visiting other Web applications for which he is authorized, the user is not challenged about his identity because he is already authenticated
  6. When the user signs off from one application, he remains logged in to other applications

How the architecture works from a developer's perspective

From the user's viewpoint, the requirements look simple. Now let's further examine how we could develop each of the many Web applications. We find the first factor common in organizational life: the many Web applications we wish to support are managed by different divisions, developed by different contractors (at different times), and deployed on different application servers (see Figure 2's UML diagram). A key success factor for us was defining an architecture that would accommodate these realities, and then properly defining the SSO solution's scope and staging. A large-scope solution must accommodate a range of somewhat dissimilar tools and provide for the fact that applications cannot all migrate at once. On the other hand, a project covering too small a scope would not be worthwhile.

Figure 2. UML for the development process of many n-tier Web applications

How the architecture works from an architect's perspective

Clearly, a suitable architecture for us had to meet several design goals. It needed to:

  • Provide SSO services to many n-tier Web applications
  • Support centralized, enforceable, and efficient security administration
  • Allow gradual deployment (i.e., not all Web applications need to adopt it at once)
  • Be consistent with J2EE standards and suitable for use with generic J2EE applications (including those not yet designed)
  • Extend to non-J2EE applications
  • Support federation (sharing) of user identities across enterprises
  • Be simple and quick to develop (to keep costs down)
  • Provide quick and easy retrofitting to existing J2EE applications
  • Work with commercial off-the-shelf (COTS) tools (e.g., LDAP) when they are available or when they represent the most appropriate source of desired functionality
  • Support different kinds of credentials for different users—both passwords and certificates, for example
  • Comply with existing security standards, such as password requirements

Approaches to authentication and SSO

We wanted a good context in which to evaluate different solutions to our problem, so we reviewed the current state of industry standards and products for authentication and SSO. We first looked at relevant parts of the J2EE specification and at the J2EE BluePrints program. Then we reviewed COTS offerings from several vendors.

What is in the J2EE spec?

Both the servlet and Enterprise JavaBean (EJB) specifications offer similar methods for accessing user identity and role information after the user authenticates. However, the servlet and EJB specifications do not define how to achieve authentication or SSO; that is left to individual vendors. In javax.servlet, programmatic security consists of the following javax.servlet.http.HttpServletRequest methods:

  • java.lang.String getRemoteUser()
  • boolean isUserInRole(String role)
  • java.security.Principal getUserPrincipal()

The getRemoteUser() method returns the client's authentication username. The isUserInRole() method determines if a remote user is in a specified security role. The getUserPrincipal() method determines the principal name of the current user and returns a java.security.Principal object.

The EJB container must provide access to the caller's security context information from the enterprise beans' instances via the getCallerPrincipal() and isCallerInRole(String role-Name) methods. The security methods in javax.ejb.EJBContext are:

  • java.security.Principal getCallerPrincipal();
  • boolean isCallerInRole(String roleName);

How do BluePrints handle authentication?

As evidence that the specifications for authentication and SSO are not yet stable, we note that successive versions of J2EE BluePrints (i.e., for the Java Pet Store) have offered different solutions to these problems. Version 1.0.1 offered a form-based architecture solution, 1.1.2 offered a servlet-based architecture, and 1.3 offered a filter architecture. We considered each architecture and its strengths and weaknesses.

Java Pet Store 1.0.1 uses form-based authentication to authenticate these interactions. In form-based authentication, a Web container designates an application-specific page containing an HTML login form. This page contains an HTML form that prompts for a username and password and displays when the user tries to access a protected resource. This solution is not portable across containers.

In Java Pet Store 1.1.2, a new servlet-based sign-in/sign-out architecture with a handler to centralize requests replaces the previous form-based login approach, enabling you to deploy the Java Pet Store on all possible J2EE platforms without modifying code. This solution is portable across containers, but the application manages it. Implementing getRemoteUser(), isUserInRole(), or getUserPrincipal() is difficult at best.

In Java Pet Store 1.3, the application implements an authentication filter to prevent unauthorized access to resources. In this approach, the filter intercepts all HTTP requests and responses. At sign-on, a flag raises in the user's session, and the filter checks for this flag in response to each request. However, in scanning the source code, we did not see calls to getRemoteUser(), isUserInRole(), or getUserPrincipal(). This leads us to conjecture that we cannot use these three methods in the current implementation. Consequently, if we developed a reusable authentication or SSO module, we could not use the standard interface between it and applications. If wrappers for the request and response were available, this would be a powerful approach.

How software vendors handle SSO

As a result of our review, it became clear that the J2EE specification does not define standard authentication or SSO approaches. Also, the BluePrints, which constantly evolve, do not offer a clear road map. Therefore, we looked at several industry offerings, three of which we describe in some detail here.

Microsoft .Net Passport

Microsoft first provided its Hotmail service at no cost, amassing more than 150 million user identities. It then used this list as the base for its .Net Passport service—an authentication service for participating Websites and services. Together with the dominance of the Windows OS and the Internet Explorer Web browser, the .Net Passport Web service could essentially make Microsoft the Internet gatekeeper. Thus far, Passport is the Web service with the largest number of registered users. And the technology behind it is simple. In our opinion, Passport's key concept is HTTP redirect:

  1. When a registered .Net Passport user clicks the standard sign-in link on a .Net Passport Single Sign-In (SSI) participating site, and he is not yet authenticated for that site, an HTTP redirect displays Microsoft's .Net Passport sign-in page.
  2. On the sign-in page, the user enters his .Net Passport sign-in name and password. The .Net Passport authenticates the user and writes a cookie to his browser.
  3. The Microsoft Passport server redirects the browser to the participating site's Web server with authentication information as parameters on the HTTP query string.
  4. The participating Web server receives the request. A server-side component, Microsoft's Passport Manager, decrypts the information received from the Microsoft Passport Server and caches the user's authentication in cookies in the user's browser. The Passport Manager also serves as a gatekeeper to verify whether an HTTP request authenticates.

For our applications, we had two objections to .Net Passport. First, it runs only on the Microsoft platform. Second, we don't want to surrender our user authentication to Microsoft.

Netegrity SiteMinder

Netegrity SiteMinder claims to support SSO across multiple domains, Web servers, and application servers, and between J2EE components. It has more than 500 large-scale customers, many of which are Fortune 2000 companies. SiteMinder agents are designed as plug-ins and can be installed on various Web servers. These Web agents serve as gatekeepers and intercept all HTTP requests. SiteMinder also supports proxy configurations. Since a proxy server acts as a gateway for all user requests, users never access the Web servers directly and the internal host name is not exposed. But there was one problem with this solution: we didn't have the budget for it.

IBM WebSphere Portal Server

We investigated IBM's SSO because its architecture is designed for an enterprise and is largely open. The key concept is a shared cookie within an Internet domain.

To enable single sign-on, IBM's SSO architecture creates a common set of server encryption keys and exports them across all servers that run the application. When users first access the site, they must log in with a user ID and password. If authenticated, an encrypted cookie writes back to the browser. Because participating servers share the cookie, you can use the cookie information to establish the user's identity when he later accesses another server in the same domain.

Our review indicated that these industry offerings differ in some important respects. The .Net Passport requires externally held credentials, requires a third party to play with Java, and presents some cost issues for us. For example, our respondents might eventually need to pay monthly fees to access our resources—fees we would not control. It would be like having an 800 number that the phone company could start charging your customers to use. Netegrity offers a comprehensive solution using plug-ins, but is expensive and aimed at large (Fortune 2000) companies. It requires a sizeable initial outlay. IBM allows SSO to Lotus Domino and later versions of WebSphere servers, but we do not have these servers.

We should note that Oracle and Sun Microsystems also offer solutions (Oracle 9iAS Portal Server and Sun One Portal Server, respectively), and undoubtedly others exist. We do not present all solutions here for two reasons. First, as we explain in the next section, the solutions share architectural similarities. Second, time for reviewing products is a limited commodity.

A single sign-on pattern

From our analysis of a few SSO implementations, we could discern a generic SSO pattern. The pattern has three major participants: gatekeeper, authenticator, and user credentials store. Hereafter, we'll name it the Gatekeeper, Authenticator, and Credential Store SSO (GAC-SSO) pattern and discuss the interactions and implementation strategies of its participants.

Participant interaction

Here is a brief description of how the pattern elements work:

  1. When a gatekeeper intercepts a request to access a protected resource, it first checks to see if a login session for the user in that Web application is established. If not, the gatekeeper checks to see if a global SSO session is established with the authenticator.
  2. If no global SSO session has been established, the user is redirected to the authenticator sign-on page and asked to provide a username and the appropriate credentials for that user (for example, password or certificate).
  3. The authenticator receives the username and credentials and verifies them against the user credential store.
  4. If verification succeeds, the authenticator establishes a global login session and directs the gatekeeper to establish a login session for the user in that Web application.
  5. The authenticator communicates with the gatekeepers by sharing cookies or by redirecting the client browser with tokens in the query string or some other method.

Implementation strategy

Of course, the gatekeeper implementation must be consistent with the container version in which it runs. Because the filter is only supported in Servlet 2.3, earlier versions must use the Java Pet Store 1.1.2's servlet-based architecture. To support these applications, we will write a gatekeeper based on javax.servlet.http.HttpServlet. This servlet is deployed as the gatekeeper for each legacy Java application that wishes to participate in SSO. As described in Java Pet Store 1.3, we will write a gatekeeper based on javax.servlet.Filter to support newer containers that comply with the Servlet 2.3 specification.

We must remove pre-existing calls to application-specific sign-on code. We don't need to recode applications that use the standard interface (e.g., getUserPrincipal()) in containers that support filtering. However, we do need to recode applications that do not use the standard interface.

You can implement the authenticator in various ways. We will implement it as a Java Web application. For organizations with only Java Web applications, this approach will suffice.

However, you could extend this approach—by adding Web services to the authenticator, for example. This extension would allow non-Java applications to access the authenticator. It would also allow the authenticator to serve as a proxy for other authenticators using Security Assertion Markup Language (SAML) running under the Simple Object Access Protocol (SOAP). In this way, we could achieve the federation of user identities. (We could also support communication with both Microsoft's .Net and Sun Microsystems' Liberty Alliance servers outside the enterprise.)

To implement the credential store, we have several options. We can use an LDAP server if available, in which case the authenticator queries the LDAP server and the LDAP server queries the credential store. If an LDAP server is not available, the authenticator can query a relational database directly.

Develop for forward compatibility

In this article, we examined a common business situation and showed how it generated a set of architectural objectives for authentication and SSO. Java specifications and BluePrints did not provide a clear strategy, and commercial solutions, although often quite powerful, are proprietary and did not fit our needs for various reasons. Developing a solution based on the GAC-SSO pattern met all of our architectural objectives. GAC-SSO might be particularly attractive to midsize organizations and to organizations that want to implement SSO without a large initial investment and without yet committing themselves to a specific vendor.

Using the GAC-SSO pattern, you can easily upgrade your solution as technologies advance. For example, Java Authentication and Authorization Service (JAAS) is now a standard part of J2SE 1.4 (Java 2 Platform, Standard Edition). J2SE 1.4 includes methods that let you link to a Kerberos 5 server. Kerberos is a technology that offers highly secure authentication and powerful methods to manage single sign-on. You can reasonably expect that, in SSO-related matters, Sun will expand J2EE 1.4 with capabilities similar to the J2SE 1.4 methods that let you easily use JAAS and Kerberos. For example, getCallerSubject() and getUserSubject() methods might be added to the specification.

We would like to thank Betty Barlow, the IT manager who directed many of the J2EE projects discussed here, for help in reviewing this article. We also thank Matt Colello, an experienced Java developer, who helped test and verify many of the ideas presented in this article.

A senior software architect with ActioNet Inc., Jian Zhong has been actively involved in J2EE architecture development for the last three years. He started Java programming in early 1996 and has been a Sun Certified Architect for the Java 2 Platform since October 1999 and a Sun Certified Enterprise Architect for the J2EE Platform since November 2000. He is the technical lead for many OIT Internet data collection projects using J2EE technologies. A senior computer specialist in the OIT systems and policy division, Mike Lehr has more than 20 years' experience in the IT area. He is an Enterprise Development Certified Professional. Recently, he has been a senior application security architect for OIT's Internet Data Collection projects using J2EE technologies.

Learn more about this topic

1 2 Page 2
Page 2 of 2