Sharing Authentication Across Domains
The JAAS configuration file mentioned earlier defines configuration IDs, which contain one or more
LoginModule definitions and corresponding attributes. The key to sharing authentication information across security domains is to have a single JAAS configuration ID that lists multiple login modules, with the second, third, and following modules specifying the
useSharedState attribute as
true (allowing security credentials to be shared).
The following is a sample configuration involving two systems, LDAP and an Oracle database, included within the same SSO architecture:
BasicAuth {
com.xyz.ldap.LDAPLoginModule
required name=LDAPSecurityDomain;
};
DBAccessAuth {
com.xyz.ldap.LDAPLoginModule
required name=LDAPSecurityDomain;
com.xyz.db.OracleLoginModule
required name=OracleSecurityDomain
useSharedState=true;
};
Two configurations are defined (BasicAuth and DBAccessAuth) to provide the flexibility of authenticating a user against one or both systems.
To implement this, the first system (LDAP) is treated as the primary system. The corresponding login module should be setup as the security realm for the J2EE container (using the BasicAuth configuration). Once a user has authenticated against the primary system (see Figure 1), she can have her security credentials propagated to the other system(s) in the chain (using the DBAccessAuth) that require authenticated access (see Figure 2).
 | |
| Figure 1: Initial System Authentication/Authorization Process Through JAAS |
 | |
| Figure 2: Subsequent System Authentication/Authorization Process Through JAAS |
This simple example contains only two subsystems, but a more complex system could include as many JAAS login modules as systems that need to share security credentials. The key difference between how authentication occurs with the two subsystems is that the primary system has JAAS authentication handled automatically (the container manages the process since the login module is configured as a security realm). The secondary subsystem (as well as any subsequent systems) must be called programmatically via the login() method of LoginContext:
LoginContext ctx = new LoginContext( "DBAccessAuth", new SimpleCallbackHandler() );
The above example assumed a fairly ideal situation in which the user's security credentials were the same for both subsystems. In real life, this is rarely the case. You often find yourself needing to integrate legacy systems with new applications, each requiring different credentials. You can accomplish this by using the original authentication information to unlock a secured datastore that houses secondary authentication information for the specified principal (one or more sets of credentials). Once you've obtained this other authentication information, you then can use it to authenticate transparently against any secondary systems. (For more details on this approach, read Vipin Samar and Charlie Lai's article (PDF): "Making Login Services Independent of Authentication Technologies".)
Voila! Single sign-on across multiple security domains by mapping primary credentials gathered from the user to secondary credentials stored on the server and used to authenticate transparently against other enterprise systems.
Single SSO in Your Enterprise Framework
SSO is a popular feature of modern enterprise systems. Unfortunately, implementing SSO can be difficult and error-prone. This brief article provides a high-level overview and guide for architects, developers, and/or managers who are interested in implementing a SSO security architecture within their current enterprise frameworks.