Kerberos SSO on Active Directory

Kerberos SSO on Active Directory

1 Overview

ExoPortal allows to use SSO (Single Sign On) with Kerberos authentication on a Microsoft Active Directory. To install this functionality, some configuration is needed, on the Active Directory server and on the application server.

In this example, we suppose that the complete name of the machine on which Tomcat server runs is ubu.exoua-int, and that it runs on the Linux host (Ubuntu 7.04). This machine must be in Windows domain. How to do it read in Samba documentation.

Our implementation makes it possible to use SPNEGO or NTLM (sometimes this two terms can be mixed, but here we will try to separate it). The client will get two authentication headers 'Negotiate' and 'NTLM' and will use supported by client (browser). In Firefox it is possible to manage authentication types, in IE this is not possible. This HOWTO will describe how to make configuration to support both authentication types. In fact for IE SPNEGO will work.

2 Active Directory configuration

On the AD server, we need to create a Kerberos identification for Tomcat Server :

  1. Create a user account for the host computer on which Tomcat Server runs in the Active Directory server. (Select New > User, not New > Machine.)

When creating the two user accounts, use the simple name of the computer, and I recommend give names as next pattern host_host-name and http_host-name. First account will be used for LDAP connection, second one will be used for authentication service via HTTP. For example, if the host name is ubu.exoua-int, create a users in Active Directory called host_ubu and http_ubu.

Note the password you defined when creating the user account. You will need it in step 3. Do not select the "User must change password at next login" option, or any other password options.

2. Configure the new user account to comply with the Kerberos protocol.

  • Right-click the name of the user account in the Users tree in the left pane and select Properties.

  • NOTE Make sure the box "Use DES encryption types for this account" is unchecked. Also make sure no other boxes are checked, particularly the box "Do not require Kerberos pre-authentication."
  • Setting the encryption type may corrupt the password. Therefore, you should reset the user password by right-clicking the name of the user account, selecting Reset Password, and re-entering the same password specified earlier.

3. Generate keys for service.

C:\> ktpass -princ host/ubu.exoua-int@EXOUA-INT -mapuser host_ubu@EXOUA-INT -crypto RC4-HMAC-NT \
-ptype KRB5_NT_PRINCIPAL -mapop set -pass 123456 -out c:\host_ubu.keytab


C:\> ktpass -princ HTTP/ubu.exoua-int@EXOUA-INT -mapuser http_ubu@EXOUA-INT -crypto RC4-HMAC-NT \
-ptype KRB5_NT_PRINCIPAL -mapop set -pass 123456 -out c:\http_ubu.keytab

4. Use the setspn utility to create the Service Principal Names (SPNs) for the user account created in step 1. Enter the following commands:

C:\> setspn -A host/ubu.exoua-int host_ubu
C:\> setspn -A HTTP/ubu.exoua-int http_ubu

5. Check which SPNs are associated with your user account, using the following command:

C:\> setspn -L host_ubu

NOTE This is an important step. If the same service is linked to a different account in the Active Directory server, the client will not send a Kerberos ticket to the server. If filter will be used secure-constraint must be removed from web.xml

6. Configuration on Linux host. This is example of file /etc/krb5.conf

[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 = EXOUA-INT                                                                                                                                                          
  default_tkt_enctypes = rc4-hmac                                                                                                                                                    
  default_tgs_enctypes = rc4-hmac                                                                                                                                                    
                                                                                                                                                                                     
[realms]                                                                                                                                                                             
  EXOUA-INT = {                                                                                                                                                                      
    kdc = test01-srv.exoua-int:88                                                                                                                                                    
    admin_server = test01-srv.exoua-int:749                                                                                                                                          
    default_domain = EXOUA-INT                                                                                                                                                       
  }                                                                                                                                                                                  
                                                                                                                                                                                     
[domain_real]                                                                                                                                                                        
  .exoua-int = EXOUA-INT                                                                                                                                                             
  exoua-int = EXOUA-INT                                                                                                                                                              
                                                                                                                                                                                     
[kdc]                                                                                                                                                                                
  profile = /etc/kdc.conf                                                                                                                                                            
                                                                                                                                                                                     
[pam]                                                                                                                                                                                
  debug = false                                                                                                                                                                      
  ticket_lifetime = 36000                                                                                                                                                            
  renew_lifetime = 36000                                                                                                                                                             
  forwardable = true                                                                                                                                                                 
  krb4_convert = false

7. Copy key generated on step 3 to the Linux machine where tomcat server runs.

8. Run the ktutil utility on the Linux machine and import keys.

andrew@ubu:~$ ktutil
ktutil: rkt host_ubu.keytab
ktutil: wkt host.keytab
ktutil: rkt http_ubu.keytab
ktutil: wkt http.keytab

You must get to new files with tickets.

3 Setup webserver

  1. Deploy an exo-tomcat, and copy the jar for SSO in lib folder and change configuration.xml file to your network settings :
<configuration>                                                                                                                     
  <component>                                                                                                                       
    <key>org.exoplatform.services.security.sso.config.SSOConfigurator</key>                                                         
    <type>org.exoplatform.services.security.sso.config.SSOConfigurator</type>                                                       
    <init-params>                                                                                                                   
      <properties-param>                                                                                                            
        <name>sso-properties</name>                                                                                                 
        <property name="charset" value="UnicodeLittleUnmarked" />                                                                   
        <property name="domain" value="EXOUA-INT" />                                                                                
        <property name="jaas-context" value="krb5.ldap-action" />                                                                   
        <property name="ldap-server" value="ldap://test01-srv.exoua-int:389/" />                                                    
        <!--                                                                                                                        
        **********************************************************                                                                  
        Default cross domain authentication is disabled.                                                                            
        NOTE: This is actual for NTLM only.                                                                                         
        For SPNEGO cross domain authentication is disabled by default.                                                              
        There is some more work to enable it for SPNEGO.                                                                            
        **********************************************************                                                                  
        -->                                                                                                                         
        <!--                                                                                                                        
        <property name="cross-domain" value="true" />                                                                               
        -->                                                                                                                         
        <!--                                                                                                                        
        <property name="redirect-on-error" value="http://google.com" />                                                             
        -->                                                                                                                         
      </properties-param>                                                                                                           
    </init-params>                                                                                                                  
  </component>

2. In exo-tomcat/conf/Catalina/localhost/, change a file portal.xml :

<Context path='/portal' docBase='portal' debug='0' reloadable='true' crossContext='true'>                                           
  <Logger className='org.apache.catalina.logger.SystemOutLogger'                                                                    
          prefix='localhost_portal_log.' suffix='.txt' timestamp='true'/>                                                           
  <Manager className='org.apache.catalina.session.PersistentManager' saveOnRestart='false'/>                                        
  <!--                                                                                                                              
  <Realm className='org.apache.catalina.realm.JAASRealm'                                                                            
         appName='exo-domain'                                                                                                       
         userClassNames='org.exoplatform.services.security.jaas.UserPrincipal'                                                      
         roleClassNames='org.exoplatform.services.security.jaas.RolePrincipal'                                                      
         debug='0' cache='false'/>                                                                                                  
         <Valve className='org.apache.catalina.authenticator.FormAuthenticator' characterEncoding='UTF-8'/>                         
  -->                                                                                                                        
   <Valve className="org.exoplatform.services.security.sso.tomcat.SSOAuthenticatorValve"/>                                    
</Context>

Secure configuration in web.xml must be changed to next:

<security-role>
    <description>a simple user role</description>
    <role-name>users</role-name>
  </security-role>

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>portal</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>users</role-name>
    </auth-constraint>

    <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>

NOTE At list one roles in web.xml must be corresponding to user group in AD.

3. Download in lib folder jcif-1.2.17.jar . We need this for support NTLM authentication.

4. In exo-tomcat/conf/jaas.conf, add :

com.sun.security.jgss.accept {                                                                                                      
  com.sun.security.auth.module.Krb5LoginModule required                                                                             
  keyTab = "/home/andrew/http.keytab"                                                                                               
  useKeyTab = true                                                                                                                  
  storeKey = true                                                                                                                   
  principal = "HTTP/ubu.exoua-int@EXOUA-INT"                                                                                        
  doNotPrompt = true                                                                                                                
  realm = "EXOUA-INT"                                                                                                               
  refreshKrb5Config = true                                                                                                          
  debug = false                                                                                                                     
  ;                                                                                                                                 
};                                                                                                                                  
                                                                                                                                    
krb5.ldap-action {                                                                                                                  
  com.sun.security.auth.module.Krb5LoginModule required                                                                             
  keyTab = "/home/andrew/host.keytab"                                                                                               
  useKeyTab = true                                                                                                                  
  storeKey = true                                                                                                                   
  principal = "host/ubu.exoua-int@EXOUA-INT"                                                                                        
  doNotPrompt = true                                                                                                                
  realm = "EXOUA-INT"                                                                                                               
  refreshKrb5Config = true                                                                                                          
  debug = false                                                                                                                     
  ;                                                                                                                                 
};

5. Add next system properties in file bin/eXo.sh

KERBEROS="-Djavax.security.auth.useSubjectCredsOnly=false \
-Djava.security.krb5.kdc=test01-srv.exoua-int \
-Djava.security.krb5.realm=EXOUA-INT"

JAVA_OPTS="$YOURKIT_PROFILE_OPTION $JAVA_OPTS $LOG_OPTS $SECURITY_OPTS $EXO_OPTS $EXO_CONFIG_OPTS $KERBEROS"

6. For portal add one more filter for initialize Identity for user org.exoplatform.services.security.sso.http.JndiIdentityInitalizerFilter this filter must be mapped before org.exoplatform.services.security.web.SetCurrentIdentityFilter on private area.

7. For Firefox, there is an additionnal configuration to do to use AD authentication : in adress bar, go to about:config. Filter on ntlm and choose "network.automatic-ntlm-auth.trusted-uris". Set string to the name of the machine where webserver run (in this exemple : set "ubu"). For IE, there is no additional configuration.

8. Go to http://ubu.exoua-int:8080/portal/private/classic If use was login windows (domain authentication) then, Active directory authentication will be used.

Instead tomcat valve org.exoplatform.services.security.sso.tomcat.SSOAuthenticatorValve can be used filter org.exoplatform.services.security.sso.http.SSOAuthenticationFilter

9. Important about using NTLM. JCIF may use MAC for signature connection to DC. In this case when one user logined, then next user may be not able login during time specified in property jcifs.smb.client.soTimeout (in ms), default 15000. This time JCIF keeps previous connection opened and may not create new one to authenticate other user. Must be set next properties to fix this jcifs.smb.client.domain, jcifs.smb.client.username, jcifs.smb.client.password. For example

-Djcifs.smb.client.domain=EXOUA-INT -Djcifs.smb.client.username=Admin -Djcifs.smb.client.password=secret"

In this case SMB connection will be signed for user.

Created by Dénarié Romain on 06/17/2008
Last modified by Dénarié Romain on 07/02/2009

Products

generated on Thu Sep 02 15:43:50 UTC 2010

eXo Optional Modules

eXo Core Foundations


Copyright (c) 2000-2010. All Rights Reserved - eXo platform SAS
2.4.30451