SPNEGO Authentication HandlerIncluding the HandlerIn 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 ClassesJCIFSSpnegoAuthenticationHandlerThis 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:
JCIFSConfigThis class is the configuration helper for JCIFS and the Spring framework. This class supports the following properties:
SpnegoNegociateCredentialsActionFirst action of a SPNEGO flow : negociation. The server checks if the negociation string is in the request header:
SpnegoCredentialsActionSecond action of a SPNEGO flow : decode the gssapi-data and build a new SpnegoCredentials. ConfigurationSet up the Active DirectoryA service account should be created. This account is called a Service Principal Name account (SPN account). Create the User
Modify the encryption algorithmWindows 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 FileThe 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 beforeIn 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 afterIn 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 accountFirst 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 usersYou 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 BrowserInternet Explorer (min 5.01)
Firefox (min 0.9)
Set Up CASSet up the login webflowThe 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:
/WEB-INF/cas-servlet.xmlTwo 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.xmlIn the bean authenticationManager, add: <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.confCopy 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 JBossJBoss 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. |