SPNEGO

Table of Contents

SPNEGO Authentication Handler

Including the Handler

In the pom.xml file for your CAS webapp (the default is ${project.home}/cas-server-webapp/pom.xml) add the following dependency:

<dependency>
     <groupId>${project.groupId}</groupId>
     <artifactId>cas-server-support-spnego</artifactId>
     <version>${project.version}</version>
</dependency>

Core Classes

JCIFSSpnegoAuthenticationHandler

This is the implementation of an AuthenticationHandler for SPNEGO supports. This Handler support both NTLM and Kerberos. NTLM is disabled by default. This class supports the following properties:

  • principalWithDomainName - boolean to enable or disable domain name in the returned netid
  • NTLMallowed - allows to authenticate using SPNEGO/NTLM token

JCIFSConfig

This class is the configuration helper for JCIFS and the Spring framework. This class supports the following properties:

  • jcifsServicePrincipal - set the Service Principal Name
  • jcifsServicePassword - set the password for the principal name
  • kerberosDebug - boolean to enable or disable the debug mode on Kerberos
  • kerberosRealm - set the Realm
  • kerberosKdc - set the KDC address
  • loginConf - path to the login.conf

SpnegoNegociateCredentialsAction

First action of a SPNEGO flow : negociation. The server checks if the negociation string is in the request header:

  • If found do nothing and return success()
  • else add a WWW-Authenticate response header and a 401 response status, then return success()

SpnegoCredentialsAction

Second action of a SPNEGO flow : decode the gssapi-data and build a new SpnegoCredentials.
Once AbstractNonInteractiveCredentialsAction has executed the authentication procedure, this action check wether a principal is present in Credentials and add correspondings response headers.

Configuration

Set up the Active Directory

A service account should be created. This account is called a Service Principal Name account (SPN account).

Create the User

  1. Start the Active Directory User and Computers from the Administration Tools menu.
  2. Right click on the Users Repository and select New > User
  3. Enter user information (by example myspnaccount for user login), press Next.
  4. Enter the password and select Password never expires and click on Next and then on Finish.

Modify the encryption algorithm

Windows Active Directory encrypts user passwords using the RC4-HMAC algorithm by default. If you are using a version of Java below 1.5 Update 7 you will need to modify the user account to use an algorithm which is supported by the Java GSS API. If you are running 1.5 Update 7 or after you can safely skip the rest of this subsection.

Open the newly created user account, select the Account tab. In the account options check Use DES encryption types for this account and click on OK. After this operation, the password must be reseted. To do so, right click on the user account and select the option Reset Password. Enter the password and press OK.

Now that the user account has been created and updated, we need to create a service principal setting for the created user account. This is automatically handled by exporting a keytab file for the created account.

Create the Keytab File

The Keytab file enables a trust link between the CAS server and the Key Distribution Center (KDC). This file contains a cryptographic key. The ktpass tool, which comes from the Windows Resource Kit, is used to generate this file. There are separate instructions depending on the version of Java you are running as mentioned in the encryption algorithm section above.

Java 1.5 Update 7 and before

In a console, enter the command:

ktpass.exe /out myspnaccount.keytab /princ HTTP/your.server.name.here@YOUR.REALM.HERE /pass * /mapuser myspnaccount
/ptype krb5_nt_principal /crypto DES-CBC-MD5

Java 1.5 Update 7 and after

In a console, enter the command:

ktpass.exe /out myspnaccount.keytab /princ HTTP/your.server.name.here@YOUR.REALM.HERE /pass * /mapuser myspnaccount
/ptype krb5_nt_principal /crypto rc4-hmac-nt

This command will generate the myspnaccount.keytab file which has to be copied on the CAS server in order to test Kerberos from a bash using the MIT Kerberos V.

Test the SPN account

First configure MIT Kerberos V on the server. The file is <literal>/etc/krb5.conf</literal>. Here is an example:

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 ticket_lifetime = 24000
 default_realm = YOUR.REALM.HERE
 default_keytab_name = /home/cas/kerberos/myspnaccount.keytab
 dns_lookup_realm = false
 dns_lookup_kdc = false
 default_tkt_enctypes = des-cbc-md5
 default_tgs_enctypes = des-cbc-md5

[realms]
 YOUR.REALM.HERE = {
  kdc = your.kdc.your.realm.here:88
 }

[domain_realm]
 .your.realm.here = YOUR.REALM.HERE
 your.realm.here = YOUR.REALM.HERE

Java 1.5 Update 7 and after users

You will need to change the default encryption types to:

default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac

Then verify that your are able to read the keytab file:

klist -k

Then verify that your are able to read the keytab file :

kinit a_user_in_the_realm@YOUR.REALM.HERE
klist

Set up Browser

Internet Explorer (min 5.01)

  1. In Internet Explorer, click Internet Options on the Tools menu.
  2. Click on the Advanced tab, click to select the Enable Integrated Windows Authentication (requires restart) check box in the Security section, and then click OK.
  3. Click on the Security tab, click to select Local Intranet then click on Sites, then click on Advanced.
  4. Enter https://your.server.name.here_ and validate by clicking on _Add and OK.
  5. Restart Internet Explorer.

Firefox (min 0.9)

  1. In Firefox, enter about:config as url and click on Go.
  2. On the line network.negotiate-auth.trusted-uris, right click on Modify and enter _https://your.server.name.here_

Set Up CAS

Set up the login webflow

The CAS 3 Login Webflow needs to be modified. This webflow is located in /WEB-INF/login-webflow.xml. There are 2 new action states which are placed before the state viewLoginForm.

<action-state id="startAuthenticate">
  <action bean="negociateSpnego" />
  <transition on="success" to="spnego" />
</action-state>

<action-state id="spnego">
  <action bean="spnego" />
  <transition on="success" to="sendTicketGrantingTicket" />
  <transition on="error" to="viewLoginForm" />
</action-state>

And 2 existing transitions need to be update:

  • In the decision-state gatewayRequestCheck, replace reference to viewLoginForm by startAuthenticate
  • In the decision-state renewRequestCheck, replace reference to viewLoginForm by startAuthenticate

/WEB-INF/cas-servlet.xml

Two beans are needed for the login flow. Those beans are:

<bean id="negociateSpnego" class="org.jasig.cas.support.spnego.web.flow.SpnegoNegociateCredentialsAction" />

<bean id="spnego" class="org.jasig.cas.support.spnego.web.flow.SpnegoCredentialsAction">
	<property name="centralAuthenticationService" ref="centralAuthenticationService"/>
</bean>

/WEB-INF/deployerConfigContext.xml

In the bean authenticationManager, add:
*_ org.jasig.cas.adaptors.spnego.authentication.principal.SpnegoCredentialsToPrincipalResolver_ as credentialsToPrincipalResolvers
*_ org.jasig.cas.adaptors.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler_ as authenticationHandlers

<bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
  <property name="credentialsToPrincipalResolvers">
    <list>
      <!--  ... the others credentialsToPrincipalResolvers ... -->
      <bean class="org.jasig.cas.support.spnego.authentication.principal.SpnegoCredentialsToPrincipalResolver" />
    </list>
  </property>
  <property name="authenticationHandlers">
    <list>
      <bean class="org.jasig.cas.support.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler">
	<property name="authentication">
	  <bean class="jcifs.spnego.Authentication" />
	</property>
	<property name="principalWithDomainName" value="false" />
	<property name="NTLMallowed" value="true"/>
      </bean>
      <!--  ... the others authenticationHandlers... -->
    </list>
  </property>
</bean>

There is also the jcifsConfig bean which needs to be added.

<bean name="jcifsConfig" class="org.jasig.cas.support.spnego.authentication.handler.support.JCIFSConfig">
  <property name="jcifsServicePrincipal" value="HTTP/your.server.name.here@YOUR.REALM.HERE" />
  <property name="jcifsServicePassword" value="the.service.password.here" />
  <property name="kerberosDebug" value="false" />
  <property name="kerberosRealm" value="YOUR.REALM.HERE" />
  <property name="kerberosKdc" value="THE.KDC.IP.HERE" />
  <property name="loginConf" value="/path/to/WEB-INF/login.conf" />
</bean>

/WEB-INF/login.conf

Copy or create the file /path/to/WEB-INF/login.conf

jcifs.spnego.initiate {
   com.sun.security.auth.module.Krb5LoginModule required storeKey=true;
};
jcifs.spnego.accept {
   com.sun.security.auth.module.Krb5LoginModule required storeKey=true;
};

Changes for JBoss

JBoss has its own security manager so specifying the login.conf file above has no effect. This was solved by amending a section in the login-config.xml file in the /SERVER-ROOT/server/default/conf directory as follows:

<application-policy name="other">
  <authentication>
    <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required">
      <module-option name="storeKey">true</module-option>
    </login-module>
  </authentication>
</application-policy>

This means that JBoss defaults to using the Kerberos login module when no others are specified. This can be extracted to a custom application policy and specified in a jboss-web.xml file so that it can be explicitly selected.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.