Applied Crypto
Hassle free single sign-on integrated with your enterprise windows domain Online Users: 6
(c) copyright
appliedcrypto.com

  Home Products Support  
Articles
References
SPNEGO SSO

PAC in a Java Web Server World

IT PRACTICE

 

SPNEGO/Kerberos authentication with Tomcat

 

 

Version 2.0

 

 

Author: Bo Friis, Partner, IT Practice A/S

 

 

Keywords: Kerberos, PAC, SPNEGO, J2EE, Security

 

 

 

 

Introduction

 

This article describes how to install and configure the IT Practice SPNEGO/Kerberos security plugins for the Tomcat application server.

 

 

Tomcat SPNEGO authenticator Valve and Realm

 

Tomcat, like other application servers, has a pluggable security interface. It's possible for a developer to replace and add new authentication mechanisms.

The security interface is roughly split into two plugin types: Authenticators and Realms.

 

The authenticator handles the authentication using some mechanism or protocol. The Realm takes care of looking up user credentials in some database.

 

We provide an authenticator valve: SPNEGOAuthenticator and a realm: SPNEGOJNDIRealm which is based on the JNDIRealm from the Tomcat project.

 

The SPNEGOAuthenticator plugin handles authentication of the user, using the Kerberos ticket provided in the SPNEGO token. If Active Directory is used as the user account database and Kerberos server, the Kerberos authentication ticket contains the Privilege Access Certificate (PAC). The PAC contains information about the user e.g. the authenticated users group membership.

 

The SPNEGOAuthenticator uses the PAC’s user-group membership information to resolve the j2ee security roles which Tomcat uses to do its authorization. This is done through a PAC (objectSid) to j2ee role mapping file [3].

 

#PAC objectSid to j2ee security role mapping
#SPNEGO/Kerberos, (c) 2005, IT Practice A/S 
domain.dc.TEST=TEST.NET
domain.dc.TEST.objectSid=S-15-72FBE2E6-814C1995-C64F68B9
objectSid.S-15-72FBE2E6-814C1995-C64F68B9-45D=spnegousers@TEST.NET
objectSid.S-15-72FBE2E6-814C1995-C64F68B9-200=Domain Admins@TEST.NET
objectSid.S-15-72FBE2E6-814C1995-C64F68B9-201=Domain Users@TEST.NET
objectSid.S-15-72FBE2E6-814C1995-C64F68B9-202=Domain Guests@TEST.NET

 

 

The mapping file contains a list of PAC objectSid’s which are unique security object identifiers in Active Directory.

 

The PAC contains group membership definitions in two ways: one containing RID’s (relative identifiers to the authenticated domain) and one containing the SID’s.

 

The RID’s will only be populated if the authenticated user has relation to the logon domain only. If a user is member of groups defined in other domains as the logon domain, the PAC objectSid’s will contain the list of groups.

 

The RID’s are only unique from within the domain. When multiple domains are setup in a trust relation, the PAC specifies which domain a group belongs to.

 

The mapping file contains domain information, which is used when the PAC only contains RID’s. The group objectSid’s is then constructed from the domain objectSid and the group RID’s.

 

The SPNEGOAuthenticator decodes the PAC and computes the group membership objectSid’s which are then mapped to a logical j2ee security role. The j2ee security role can be anything but must match the security roles defined in the Tomcat web application deployment descriptor.

 

 

Installing sample web application and configuring security in Tomcat

 

The sample application has one protected URL defined in the deployment descriptor:

 

   <security-constraint>
      <web-resource-collection>
         <web-resource-name>
            Restricted Area
         </web-resource-name>
         <url-pattern>/spnegoauthplugin</url-pattern>
      </web-resource-collection>
      <auth-constraint>
         <role-name>spnegousers@TEST.NET</role-name>
      </auth-constraint>
   </security-constraint>
 
   <security-role>
      <description>spnegousers@TEST.NET</description>
      <role-name>spnegousers@TEST.NET</role-name>
   </security-role>

 

The URL /spnegoauthplugin is protected by a j2ee security role called spnegousers@TEST.NET. Using the objectSid’s mapping in the previous example we see that the user must be member of the Active Directory group defined by the SID: S-15-72FBE2E6-814C1995-C64F68B9-45D (or RID: 45D):

 

objectSid.S-15-72FBE2E6-814C1995-C64F68B9-45D=spnegousers@TEST.NET

 

This is a group in example Active Directory called “spnegousers” defined in the domain TEST.NET. Note that the object SID’s will be different in other setups.

 

 

 

Now that we have configured the web application to be protected by the j2ee security manager in Tomcat, we must configure the Tomcat to handle j2ee security. This is done bu adding a Valve and optionally a Realm to the Tomcat server.xml configuration file.

 

   <Engine …>
      <Host …>
         <Context 
            path="/spnegosample" 
            docBase="spnegosample.war" 
            debug="99">
         
            <Valve className="dk.itp.tomcat.SPNEGOAuthenticator"
                basicAuth=”false”
                debug="99"/>
         </Context>
      </Host>
   </Engine>

 

This adds the SPNEGOAuthenticator to the spnegosample web application. The “basicAuth” property defines that BASIC authentication will be used if SPNEGO should fail, which is typically caused by configuration errors.

 

If “fallback” to BASIC authentication is configured, a LDAP based realm is needed to lookup the user in Active Directory. This is handled by the SPNEGOJNDIRealm.

 

The SPNEGOJNDIRealm is based on the Apache.org version, and uses the exact same configuration parameters.

An example:

 

   <Engine …>
      <Realm className="dk.itp.tomcat.SPNEGOJNDIRealm" 
         debug="99"
         connectionName="cn=Administrator,cn=users,dc=test,dc=net"
         connectionPassword="password" 
         connectionURL="ldap://192.168.202.2:3268"
         userBase="DC=TEST,DC=NET"
         userSearch="(sAMAccountName={0})"
         userRoleName="memberOf"
         roleBase="DC=TEST,DC=NET"
         roleName="objectSid"
         roleSearch="(member={0})"
         roleSubtree="true"
         userSubtree="true" />
   </Engine>

 

Note that the connectionURL, connectionName, connectionPassword, userBase, roleBase must be changed according to specific domain and Active Directory definitions.

 

 

Setting up the pac-j2ee mapping (objectSid to j2ee security role)

 

The sample web application contains a URL that shows the PAC and Kerberos content of the SPNEGO encoded Kerberos ticket.

 

The URL /spnegosample/spnegopacservletfilter will produce the following output:

 

General User Info

getAuthType

SPNEGO/Kerberos

getUserPrincipal()

class dk.itp.servletfilter.SpnegoPrincipal[test@TEST.NET]

getUserPrincipal() instanceof SpnegoPrincipal.class

true

((SpnegoPrincipal)getUserPrincipal).getServer()

HTTP/webserver.test.net@TEST.NET

((SpnegoPrincipal)req.getUserPrincipal()).getPacLogonInfo()

primaryGroupRid=513

logonDomain=TEST

userName=test

useridRid=1108

objectSids=[S-15-72fbe2e6-814c1995-c64f68b9-45d, S-15-72fbe2e6-814c1995-c64f68b9-200, S-15-72fbe2e6-814c1995-c64f68b9-202, S-15-72fbe2e6-814c1995-c64f68b9-201, S-15-72fbe2e6-814c1995-c64f68b9-461]

logonSrv=SPNEGO

fullName=test testesen

logonDomainSid=S-15-72fbe2e6-814c1995-c64f68b9

j2ee roles

[S-15-72fbe2e6-814c1995-c64f68b9-45d, S-15-72fbe2e6-814c1995-c64f68b9-200, S-15-72fbe2e6-814c1995-c64f68b9-202, S-15-72fbe2e6-814c1995-c64f68b9-201, S-15-72fbe2e6-814c1995-c64f68b9-461]

getRemoteUser

test@TEST.NET

isUserInRole('spnegousers')

false

isUserInRole('spnegousers@TEST')

false

 

User PAC info

#pac-j2ee.properties

domain.dc.TEST.objectSid=S-15-72fbe2e6-814c1995-c64f68b9

objectSid.S-15-72fbe2e6-814c1995-c64f68b9-45d=RID.45d@TEST   # REDEFINE THIS ROLE

objectSid.S-15-72fbe2e6-814c1995-c64f68b9-200=Domain Admins@TEST

objectSid.S-15-72fbe2e6-814c1995-c64f68b9-202=Domain Guests@TEST

objectSid.S-15-72fbe2e6-814c1995-c64f68b9-201=Domain Users@TEST

objectSid.S-15-72fbe2e6-814c1995-c64f68b9-461=RID.461@TEST   # REDEFINE THIS ROLE

 

The last section, the User PAC info, shows the objectSid’s including the predefined RID’s. This section can be cut-pasted into the pac-j2ee.properties file.

 

The above User PAC info includes two groups that is not predefined by Microsoft. These are groups that are created using the user administration and manually assigned to the authenticated user.

 

The pac-j2ee.properties can be corrected to map the real group name in Active Directory.

 

The URL /spnegopacservletfilter can be run for each multiple users and the output can be merged into the pac-j2ee.properties mapping file.

 

It is recommended that the auto generated RID codes in pac-j2ee.properties file are mapped to logical names. Non standard Object SID’s and RID’s will be regenerated every time a new domain controller is deployed. Nor will groups with the same name in different domains have the same RID.

 

Active Directory can be accessed using an LDAP browser. Microsoft has one included in their resource kit called LDP. This can be downloaded free-of-charge.

 

Below there is an example of the user defined spnegousers group:

 

Expanding base 'CN=spnegousers,CN=Users,DC=TEST,DC=NET'...
Result <0>: (null)
Matched DNs: 
Getting 1 entries:
>> Dn: CN=spnegousers,CN=Users,DC=TEST,DC=NET
         5> member: CN=webserver,CN=Users,DC=TEST,DC=NET; CN=userxx,OU=ou11,OU=ou1,DC=TEST,DC=NET; CN=test5,CN=Users,DC=TEST,DC=NET; CN=Bo Friis,CN=Users,DC=TEST,DC=NET; CN=test,CN=Users,DC=TEST,DC=NET; 
         1> cn: spnegousers; 
         1> groupType: -2147483646; 
         1> instanceType: 4; 
         1> distinguishedName: CN=spnegousers,CN=Users,DC=TEST,DC=NET; 
         1> objectCategory: CN=Group,CN=Schema,CN=Configuration,DC=TEST,DC=NET; 
         2> objectClass: top; group; 
         1> objectGUID: 712c3320-dc87-472b-9d80-4d2d16637675; 
         1> objectSid: S-15-72FBE2E6-814C1995-C64F68B9-45D; 
         1> name: spnegousers; 
         1> sAMAccountName: spnegousers; 
         1> sAMAccountType: 268435456; 
         1> uSNChanged: 28627; 
         1> uSNCreated: 5704; 
         1> whenChanged: 3/20/2005 22:58:53 Romance Standard Time Romance Daylight Time; 
         1> whenCreated: 6/23/2004 22:25:16 Romance Standard Time Romance Daylight Time; 
-----------

 

Looking at the attribute objectSid we see that the highlighted RID 45D is mapped to the spnegousers group. This information can be used to replace the RID.45d@TEST entry in the pac-j2ee.properties with the entry spnegousers@TEST value.

 

 

Testing

 

The URL /spnegosample/spnegoauthplugin activates the HelloWorldServlet which is protected by the Tomcat Authenticator plugin. If everything is setup correctly, it will produce something similar to the following output:

 

 

General User Info

getAuthType

SPNEGO/Kerberos

getUserPrincipal()

class dk.itp.tomcat.SpnegoPrincipal[test]

getUserPrincipal() instanceof SpnegoPrincipal.class

false

getRemoteUser

test

isUserInRole('spnegousers')

false

isUserInRole('spnegousers@TEST')

true

 

Note that the user is member of the spnegousers@TEST group. This is only possible when using the SPNEGOAuthenticator plugin.

 

When using the Servlet Filter, the method isUserInRole() will always return false, since the user never logins in to the Tomcat security manager.

 

 

Conclusion

 

Kerberos and SPNEGO enables desktop single sign-on on web applications deployed on the Tomcat server. It is based on Active Directory and the Tomcat running on top of SUN JDK 1.4+.

 

We have shown how to deploy and configure an SPNEGO/Kerberos Tomcat authenticator and SPNEGO/Kerberos servlet filter.

 

 

References

 

[1] Tomcat documentation pages, http://jakarta.apache.org/tomcat/tomcat-4.0-doc/realm-howto.html

 

[2] SPNEGO/Kerberos authentication using JGSS, 2004, Friis, http://appliedcrypto.com/portalprotect/SPNEGO%20authentication%20using%20JGSS.pdf

 

[3] PAC (Privilege Access Certificate) in a Java Web Server World, 2005, Friis, http://appliedcrypto.com/spnego/pac/ms_kerberos_pac.html

 

 

 

About the author

 

Bo Friis is working as a security consultant for IT Practice in Denmark. He has specialized in security protocols and implementations. He is working on security solutions for various customers. He is the co. architect and developer of the PortalProtect product and the architect and developer of SPNEGO/Kerberos product.

 

He has designed and developed the initial version of OpenSign and OpenLogon, a set of applets that supports digital signature using X.509 certificates over the XMLDSIG standard. The result was donated to the open source OpenOCES project.

 

Bo Friis holds a Masters degree in Cryptography from the University of Aarhus in Denmark. He also holds a Master of Science degree in Electrical Engineering from the Technical University of Denmark.

He can be reached at email: jbf_AT_practice.dk

 

(c) 2005 IT Practice and Bo Friis, appliedcrypto.com

 

 

Copyright Notice and Legal Stuff

 

All software parts of the SPNEGO/Kerberos product are copyright IT Practice A/S or their respective parties.

 

When using the SPNEGOJNDIRealm for Tomcat, the following message must be noted according to license terms: This product includes software developed by the Apache Software Foundation (http://www.apache.org/)". Copyright (c) 1999-2002 The Apache Software Foundation.  All rights reserved.

(c) copyright appliedcrypto.com AppliedCrypto News RSS feed