Single Sign On (SSO) into
Sun Java System Access Manager using a custom java client application which uses kerberos authentication was accomplished by using JAAS with kerberos, then using SPNEGO GSS. The result is an Access manager session which can be used for authorization in the java application. This can then be used in the client application for things like requesting protected (by Access Manager policy agents) web content or making J2EE calls to EJB's which are protected by J2EE security.
Here is the solution used to solve this problem I was faced with recently that did a nice job of splicing together a kerberos authentication into a custom Java application, then used Access Manager's Windows Desktop SSO module to obtain a session for web SSO and calling EJB's which use J2EE security. The beta version of Java SE 6 was used for this project.
Background of Java SE 6 features which make this possible
New Security Features in JDK 6
J2SE now supports SPNEGO mechanism in Java GSS.
Java GSS is a framework that can support multiple security mechanisms; however GSS-API does not prescribe the method by which GSS-API peers can establish whether they have a common security mechanism. The Simple and Protected GSS-API Negotiation (SPNEGO) mechanism is a pseudo security mechanism that enables GSS-API peers to securely negotiate a common security mechanism to be used. The SPNEGO protocol is used to negotiate which security mechanism should be adopted.
Currently Java GSS applications specify a unique object identifier (OID) to select the underlying security mechanism. For e.g. Java GSS applications specify Kerberos mechanism |OID "1.2.840.113554.1.2.2 | to use Kerberos mechanism. |Oid mechOid = new Oid("1.2.840.113554.1.2.2"); |
To select SPNEGO security mechanism, Java GSS applications would need to specify the SPNEGO mechanism |OID "1.3.6.1.5.5.2". | |Oid mechOid = new Oid("1.3.6.1.5.5.2); |
Support for SPNEGO improves interoperability with Microsoft products. SPNEGO protocol is heavily used to interoperate with Microsoft server over HTTP, to support HTTP-Based Cross-Platform Authentication via the Negotiate Protocol. J2SE now supports SPNEGO authentication scheme in HTTP as well. Please check list of new networking features for Mustang.
For Java GSS with SPNEGO, you can use the Java GSS sample code from the tutorial, and replace the Kerberos Oid with the SPNEGO Oid. Here is the JGSS tutorials that includes the samples:
JGSS tutorials
HTTP Negotiate authentication
This adds support for the "Negotiate" HTTP authentication scheme
defined by Microsoft. Negotiate allows multiple underlying
authentication mechanisms to be supported, and in each instance, one
of these mechanisms is chosen for use. Currently, Kerberos is the
only supported mechanism.
Solution Created
Here are some of the relevant pieces of the first sample application for the solution which is based on the samples that are available in the Java Security tutorial with the relevant additional pieces.
It uses JAAS for kerberos SSO, then sets up JGSS for SPNEGO before opening a URL into Access Manager where a session is created for Access Manager SSO.
Configuration details:
A Login Configuration file for JAAS is used to Specify that Kerberos v5 is a required login module for the sample application.
Here is the contents of this file:
searchkrb5 {
com.sun.security.auth.module.Krb5LoginModule required client=true useTicketCache=true;
};
Then in the sample application use the JAAS kerberos module for authentication:
//Specify the login configuration
System.setProperty("java.security.auth.login.config","searchkrb5.conf");
//Specify the Kerb 5 stuff
System.setProperty("java.security.krb5.realm","TCPIP.COM");
System.setProperty("java.security.krb5.kdc","win2k3.TCPIP.COM");
LoginContext lc = null;
try {
lc = new LoginContext(searchkrb5.class.getName(),new SampleCallbackHandler());
lc.login();
}
catch (LoginException le) {
System.out.println("Logon failed: " + le);
System.exit(-1);
}
Now we can call a method with our new credentials:
Subject.doAs(lc.getSubject(), new AcessManagerSSOInitiate());
Now we can get an Access Manager session:
/*
* This Oid is used to represent the Kerberos version 5 GSS-API
* mechanism. It is defined in RFC 1964. We will use this Oid
* whenever we need to indicate to the GSS-API that it must
* use Kerberos for some purpose.
*/
//Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
//above is for kerberos, below is for SPNEGO
GSSManager manager = GSSManager.getInstance();
Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
Oid mechOid = new Oid("1.3.6.1.5.5.2");
/*
* Create a GSSName out of the server's name. The null
* indicates that this application does not wish to make
* any claims about the syntax of this name and that the
* underlying mechanism should try to parse it as per whatever
* default syntax it chooses.
*/
GSSName serverName = manager.createName("http/win2k3.tcpip.com", null);
/*
* Create a GSSContext for mutual authentication with the
* server.
* - serverName is the GSSName that represents the server.
* - krb5Oid is the Oid that represents the mechanism to
* use. The client chooses the mechanism to use.
* - null is passed in for client credentials
* - DEFAULT_LIFETIME lets the mechanism decide how long the
* context can remain valid.
* Note: Passing in null for the credentials asks GSS-API to
* use the default credentials. This means that the mechanism
* will look among the credentials stored in the current Subject
* to find the right kind of credentials that it needs.
*/
GSSContext context = manager.createContext(serverName, mechOid, null, GSSContext.DEFAULT_LIFETIME);
Now we can create and Access Manager session and continue using the Access Manager API's (which is another topic well documented in Access Manager samples.
URL url = new URL("http://jes3.companyxyz.com/amserver/UI/Login?module=WindowsDesktopSSO&org=companyxyz.com&goto=http://jes3.companyxyz.com/amconsole");
InputStream ins = url.openConnection().getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
That's it. The SPNEGO negotiation and validation of the user's kerberos credentials happen automatically. Once you process this stream (including an Access Manager session cookie), you will have the ability to use the Access Manager's API's in your application, but that is the subject of a future blog.
For more information, here is a great resource for Access Manager and kerberos:
Cross-realm Kerberos authentication with Access Manager
Infrastructure Required:
Access Manager
Access Manager's Windows Desktop SSO module configured
Active Directory and a windows client in the domain (other kerberos servers and client will also work)
Jave SE 6 (beta was used)
Posted at 09:04AM Dec 10, 2006
by harcey in Identity |