Saturday, June 18, 2011

Configuring Kerberos SSO for JEE application deployed on WebLogic instance running on Linux host

No room for confusion!

Kerberos – It is a computer network authentication protocol, which allows individuals communicating over an insecure network to prove their identity to one another in a secure manner.

SPNEGO – Stands for "Simple and Protected GSS-API Negotiation Mechanism", and is a pseudo security mechanism that enables GSS-API peers to determine in-band whether their credentials support a common set of one or more GSS-API security mechanisms; if so, it invokes the normal security context establishment for a selected common security mechanism. The primary intention of SPNEGO is to allow a client and server to negotiate a security mechanism for authentication.

KDC – Stands for Key Distribution Center. It is the authentication server in a Kerberos environment. Its function is to distribute tickets  for access to the services. Generally, the KDC is composed of three parts: Database as the container for entries associated with the users and services, Authentication Server (AS) for replying to the initial authentication request from the client and Ticket Granting Server (TGS) for granting tickets.

Kerberos Realm – The term realm indicates an authentication administrative domain. Its intention is to establish the boundaries within which an authentication server has the authority to authenticate a user, host or service. For example, Windows 2003 server domain.

Ticket – A ticket is something a client presents to an application server to demonstrate the authenticity of its identity.

SPNEGO token – It is like an assertion token which is composed by negotiation mechanism information like mechanism type and mechanism token. it consist of two types, an init token (NegTokenInit) and a response token (NegTokenResp).

TGT – Stands for Ticket-Granting Ticket. The Ticket Granting Server is the KDC component which distributes service tickets to clients with a valid TGT, guaranteeing the authenticity of the identity for obtaining the requested resource on the application servers.

GSS-API – Stands for "Generic Security Service Application Program Interface" and is an IETF standard to unify the interface of programming against (authentication) security services. For Kerberos, GSS-API provides a unified interface against different implementations (libraries).


Now here is what we have to do

Step 1 - Configure your network domain to use Kerberos
 

- The first step is to locate your domain controller, and ensure the Kerberos and AD services are running. 


- We will need utilities "setspn.exe" and "ktpass.exe". These come with Microsoft Support Tools package. Let us say it is installed into "%ProgramFiles%\Support Tools"

- Let us say that WebLogic instance is listenting using FQDN "mac5.localdomain.com" (say IP address 192.169.0.5). Generally, "mac5" would be alias "localdomain.com" would be domain.

- Let us say the AD and KDC are both on windows 2003 server. Let us suppose the server is located at "win2003sp2.localdomain.com" with an IP address say "192.169.0.4"

- Confirm that reverse lookups for above two IP addresses is working. Check nslookups are also working for two FQDNS on both the machines (AD/KDC server and Linux machine hosting WebLogic instance)

1.1 Configure your WLS machine to locate the KDC server:

HOW: You need to create a krb5.ini file (or /etc/krb5.conf in case of linux), in the C:\winnt folder. This file contains configuration options for the clients, such as where the KDC is.


################ Example krb5.conf file ################
[libdefaults]
 default_realm = LOCALDOMAIN.COM
 default_tkt_enctypes = des-cbc-md5
 default_tgs_enctypes = des-cbc-md5
 #ticket_lifetime = 26000

[realms]
 LOCALDOMAIN.COM = {
  kdc = 192.169.0.4
  admin_server = win2003sp2
  default_domain = LOCALDOMAIN.COM
 }

[domain_realm]
 .localdomain.com = LOCALDOMAIN.COM

[appdefaults]
 autologin = true
 forward = true
 forwardable = true
 encrypt = true
################ Example krb5.conf file ################

Step 2 - Create an account for the WLS server

Create a user account in AD. This is the user under which WebLogic instance will run as a service. Say, we create a user "wls1034".

How:
  • Launch Programs/Administrative Tools/Active Directory Users and Computers tool.
  • Right click on the Users node and select New/User. (Do not select Machine)
  • Type in the user name in the "Full Name" field (without any blank spaces) and in the "Logon Name” field. Ideally both of them should be same.
  • Click Next, and enter a password
  • Verify that none of the password options are checked. Click Next.
  • Click Finish.
Configure your user to comply with the Kerberos protocol: The encryption type for this account must be DES, and the account must require Kerberos pre-authentication.

How:
  • Locate your newly created user in the Users tree in the left hand pane.
  • Right-click on the user node, and select Properties.
  • Click on the "Account" tab.
  • Check the box: "Use DES encryption types for this account". (* see below note first)
  • Ensure no other box is checked, specifically: "Do not require Kerberos pre-authentication". It should be unchecked if you find it checked.
  • Click OK.

* WLS 10.3.3 and older ones support only DES encryption (except for installations using  IBM JDKs). So this needs to be set. For versions 10.3.4 and later, encryption types like AES128, AES256, etc are also supported against AD 2008. Enable the encryption of your choice by checking the appropriate checkbox in account-tab area.

Beware! Usually setting the encryption type will corrupt the password. It is recommended at this point to reset the password of this user, by right clicking on the user, selecting "Reset Password" and re-entering the same password specified earlier.


Step 3 - Define a Service Principal Name and create a keytab for the service

Next step involves creating Service Principal Names (SPNs) for the user account that we created in step-1. Principal essentially represents your WebLogic server in the Kerberos realm. Beware that if same SPN is linked to multiple user accounts in the AD server, the client will not send a Kerberos ticket to the WebLogic server. SPNs are of the form “HTTP/mac5.localdomain.com” or  "HOST/mac5.localdomain.com”. For confirming whether the SPN(that you intend to use) is not already linked to some other user account please follow the steps:
a. use following command to export the AD data to some file:
        ldifde –f  <filename> –s <domain_controller>

b. Open the file in text editor and search for the SPN that you intend to use in the current setup. If you find any such SPN already defined, get the corresponding CN name. This CN name represents account name.

Or, as an alternative to "a" and "b" on latest version of Windows (like Windows 7, etc), we can execute  following flavor of Windows "setspn" command to detect already existing SPNs:
        setspn -Q <SPN>
         c. List the SPN associated with the account name:
                  setspn -l <account_name>   
d. Delete the <SPN> for the <account_name>
        setspn -d <SPN> <account_name>
Or else you can choose a different SPN altogether.

We will create following two SPNs:
  • HTTP/<alias>
  •  HTTP<fqdn>
Now, the commands used to generate the SPN and store the principals (essentially UPNs of AD account) vary depending on whether the WebLogic is running on Linux or a Windows machine.


On AD machine, navigate to "%ProgramFiles%\Support Tools" and execute following commands:

If WLS is running on linux machine:
  • setspn -a HTTP/mac5 wls1034
  • ktpass -princ HTTP/mac5.localdomain.com@LOCALDOMAIN.COM -pass weblogic1 -mapuser wls1034 -out mac5keytab -crypto DES-CBC-MD5 -TrustEncryp DES


 
If WLS is running on Windows machine:
  • setspn -a HTTP/mac5 wls1034
  • setspn -a HTTP/mac5.localdomain.com wls1034
  • ktab -k mac5keytab -a wls1034 weblogic1

Notes:
  • "ktpass" has a kind of effect that it will change the principal name (a UPN of user account) on the AD server from <account-name> to HTTP/<wls fqdn or alias>. And consequently, the keytab is generated for a principal "HTTP/<wls fqdn or alias>@<REALM.NAME>". Nothing to worry yet, but we will be adjusting our JAAS configuration file later on to reflect this.
  •   In the remaining part of document, we will use "HTTP/mac5.localdomain.com@LOCALDOMAIN.COM" as principal if WLS is on Linux machine while as  "wls1034@LOCALDOMAIN.COM" would be used used as principal if WLS is on Windows machine. This principal is essentially an account's "UPN" which gets modified in case of "ktpass" execution and not in "ktab" case, and hence this complexity.


Now transfer the keytab files to machine where WebLogic is running. Copy it into DOMAIN_HOME.

Note: If you need to create two keytabs for some reason (like one for HOST and one for HTTP) then merging of two keytabs into one can also be done. This is done using linux utility "ktutil". Open a command terminal and navigate to DOMAIN_HOME. Execute "ktutil" command. This will open a "ktutil" prompt. Type in following commands:

           ktutil: "rkt mac5.HOST.keytab"
           ktutil: "rkt mac5.HTTP.keytab"
           ktutil: "wkt mac5keytab"
           ktutil: "q"

Now, confirm that the principal are listed using following command:

           [root@mac5 TestDomain1]# klist -ke -t mac5keytab

This will output following:

           Keytab name: FILE:mac5keytab
           KVNO Timestamp         Principal
           ---- ----------------- --------------------------------------------------------
              5 06/18/11 11:46:05 HTTP/mac5.localdomain.com@LOCALDOMAIN.COM (DES cbc mode with RSA-MD5)

Step 4. Verify your Kerberos configuration is working (on WLS machine):

It is crucial at this specific point to verify that Kerberos is set up properly and that your principal and keytab are valid. If they are not, then there is no point in going further in the process. We now test the kerberos connectivity using our principals. For this we will use linux utility "kinit"

If WLS is running on linux machine:

           [root@mac5 TestDomain1]# kinit -J-Dsun.security.krb5.debug=true  -kV -t mac5keytab HTTP/mac5.localdomain.com@LOCALDOMAIN.COM
           Authenticated to Kerberos v5   

If WLS is running on Windows machine:

           C:\Users\apir>kinit -J-Dsun.security.krb5.debug=true -k -t mac5keytab wls1034
           New ticket is stored in cache file C:\Users\apir\krb5cc_apir

Step 5 - Configure the client/browser for single sign on

Set up the browser to use Kerberos:

HOW:
  1. Got to Tools --> Internet Options
  2. Select the "Security" tab
  3. Click on "Local Intranet" Icon.
  4. Click "Sites" button. This will show a "Local Intranet" Popup.
  5. Make sure the option "Include all local (intranet) sites not listed in other zones" option selected. (Windows XP Only).
  6. Click on "Advanced" Button. In the new popup window add the URL for the machine hosting weblogic.
  7. Click OK to save your settings.
  8. In the "Security" tab, Click "Custom Level" button.
  9. In the "Security Settings" dialog, under "User Authentication" section, make sure "Automatic logon only in Intranet zone" option is selected.
  10. Click OK to save your settings.
  11. Go to "Connections" tab ---> LAN Settings.
  12. If you have a proxy server enabled, Click on "Advanced" button. Make sure you add the URL for the machine hosting weblogic in the "Exceptions" box.
  13. In the "Internet Options ---> Advanced" tab, make sure "Enable Integrated Windows Authentication (requires restart)" option is checked. Click "OK". (If this option is not selected previously, you need to close all browser instances for the setting to take effect).

Step 6 - configure the WLS server for Single Sign On

6.1 Configure JAAS on WLS:
JAAS allows dynamic configuration of login modules. We need to specify a JAAS configuration file that specifies the login modules to use.

How:
Create a JAAS login configuration file in the DOMAIN_HOME. Let us name it "jaas.conf". Its contents would be similar to:

For Weblogic running with JDK 1.4 and 1.5
If WLS is running on linux machine:

com.sun.security.jgss.accept {
   com.sun.security.auth.module.Krb5LoginModule Required
   principal="HTTP/mac.5localdomain.com@LOCALDOMAIN.COM" keyTab=mac5keytab
   useKeyTab=true storeKey=true debug=true;
};
If WLS is running on Windows machine:
com.sun.security.jgss.accept {
   com.sun.security.auth.module.Krb5LoginModule Required
   principal="wls1034@LOCALDOMAIN.COM" keyTab=mac5keytab
   useKeyTab=true storeKey=true debug=true;
};

For WebLogic running with JDK 1.6
If WLS is running on linux machine: 

com.sun.security.jgss.krb5.initiate {

com.sun.security.auth.module.Krb5LoginModule required principal="HTTP/mac5.localdomain.com@LOCALDOMAIN.COM" useKeyTab=true keyTab=mac5keytab storeKey=true
debug=true; };

com.sun.security.jgss.krb5.accept {

com.sun.security.auth.module.Krb5LoginModule required principal="HTTP/mac5.localdomain.com@LOCALDOMAIN.COM" useKeyTab=true keyTab=mac5keytab storeKey=true
debug=true;

};

If WLS is running on Windows machine:
com.sun.security.jgss.krb5.initiate {

com.sun.security.auth.module.Krb5LoginModule required principal="wls1034 @LOCALDOMAIN.COM" useKeyTab=true keyTab=mac5keytab storeKey=true
debug=true; };

com.sun.security.jgss.krb5.accept {

com.sun.security.auth.module.Krb5LoginModule required principal="wls1034 @LOCALDOMAIN.COM" useKeyTab=true keyTab=mac5keytab storeKey=true
debug=true;

};


Beware! Be extra cautious while creating this file. Any syntax or spelling mistake will have the server throw an exception when connecting to the KDC, and fail authentication.

Now, edit the startup script of WebLogic instance to include following JAVA system properties against JAVA_OPTIONS variable:

           JAVA_OPTIONS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true -Djava.security.auth.login.config=jaas.conf -Djavax.security.auth.useSubjectCredsOnly=false -Dweblogic.security.enableNegotiate=true -Djava.security.debug=configfile,configparser,gssloginconfig ${JAVA_OPTIONS}"


Note that I have included some debug properties as well. You can remove them once you have a working setup.

6.2 Configure the Negotiate Identity Assertion provider:

Create this type of asserter from "security realms"/<realm name>/Providers/Authentication Providers“. Once created, disable "Form based authentication” from provider specific tab.

 6.3 Define a security constraint on the WLS resource you will be accessing: 
In order for authentication to take place, the resource (JSP or Servlet) being accessed must be protected, and for the web application to participate in Single Sign On with the client, the authentication mechanism must be set to CLIENT-CERT. This will enable WLS authentication to rely on the Kerberos authentication information. However, the obtained user name must be found inside the WLS users repository. If WLS if configured to use the same AD server as the one associated to the KDC, then the user will certainly authenticate. Otherwise, you must make sure that such a user can be found in the WLS user repository. Moreover, Kerberos does not handle authorization; this will be resolved within Weblogic. In order to authorize your Windows user to access the resource, you need to restrict access to the resource to a specific role. This role will translate into a set of principals. If the logged in user of the Client machine belongs to that set of principals, then the resource will be automatically granted to the browser.

HOW:
The snippet from web.xml file of the web application in question would be similar to:
<security-constraint> 
    <display-name>Security Constraint for SSO </display-name>                  
    <web-resource-collection>        
         <web-resource-name>My webapp</web-resource-name>    
         <description>Group of Users</description>
         <url-pattern>/*</url-pattern>
     </web-resource-collection>              
     <auth-constraint>
         <role-name>SSORole</role-name>   
     </auth-constraint>
</security-constraint>
<login-config>           
     <auth-method>CLIENT-CERT</auth-method>      
</login-config>          
<security-role>                       
     <description>Role description</description>                
     <role-name>SSORole</role-name>    
</security-role>
Using this snippet, we declared a logical application security role "SSORole" and instructed the webcontainer to grant access to "/*" resources to users with "SSORole" only. Of course, the role "SSORole" needs to be mapped to actual principal name in weblogic.xml, Example:

<security-role-assignment>
  <role-name>SSORole</role-name>
  <principal-name>weblogic</principal-name>
  <principal-name>Testers</principal-name>
</security-role-assignment>
Entry "principal-name" can represent a group name as well as a specific username know to WebLogic security realm either using default authenticator, or other available (and configured) authenticators.

Now all you need to do is deploy your application and restart the WebLogic instance. Enjoy!

No comments:

Post a Comment