Wednesday, June 8, 2011

Configuring WLS for SSO using Kerberos protocol

In this post we will go step-by-step on how to configure WLS and  Windows Integrated Authentication using Kerberos protocol.


I will not go over the theory of how Kerberos works and the general idead behind it. There's plenty of documentation in the web that covers it much better than I could do.


I always found it hard to get a detailed guide on how to implement the solution with a real example with details.


So, after struggling with Kerberos in several customer's issues and implementations, I decided to post here my experience with this small tutorial.


I hope it helps people to get started.






I. Required Environment


a. KDC/AD machine
OS: Windows 2003 Server
Domain: kerberossso.com
Machine: win2003
IP: 192.168.0.100


b. Windows Client
OS: Windows XP SP3
Domain: kerberossso.com
Machine: win-xp
Client: IE 7
User: wlsuser3 (this user needs to be created on the AD and will log on to the kerberossso domain)
Pass: Letmein123
IP: 192.168.0.101


c. Weblogic Server 10.3.3
OS: Oracle Enterprise Linux 5
Machine: wlshost
IP: 192.168.0.102
WLS Domain: KerberosDomain (A standard WLS domain with just the AdminServer)


Note: Additional files and test application to complete this step-by-step will be provided at the end of the post.




II. AD Setup for client machine


a. create the following user in AD
b. User: wlsuser3
c. Password: Letmein123






d. Log on in the Windows XP machine (Client) with wlsuser3/Letmein123 in kerberossso.com domain






III. AD Setup for Weblogic Server


a. Create a user in the AD to represent the WLS. When creating the user account, use the simple name of the computer. For example, if the host is named myhost.example.com, create a user in Active Directory called myhost.
b. Create a new user wlshost and set the password to Letmein123
c. The user account's encryption type must be DES and the account must require Kerberos pre-authentication.






d. Reset the password to Letmein123 again (Setting the encryption type may corrupt the password)
e. Create the Service Principal Names (SPNs) for the user account created in step a:


setspn -A HTTP/wlshost wlshost


f. Check if the SPN was created successfully. 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.


setspn -L wlshost






g. Create a keytab file:


ktpass -princ HTTP/wlshost@KERBEROSSSO.COM -pass Letmein123 -mapuser wlshost -mapOp set -DesOnly -crypto DES-CBC-CRC -pType KRB5_NT_PRINCIPAL -SetPass -out wlshost.keytab


h. Reset the password for wlshost user again. For some reason, in my tests, I had to reset the password before testing the keytab file, otherwise it fails to authenticate.






IV. Configuring the WLS Machine to access the KDC


a. Test the keytab file
 a1. Create a Kerberos Configuration File (krb5.conf). OEL has a sample krb in /etc/krb5.conf
 a2. Edit this file and replace it with the following contents:

[logging]
 default = FILE=/root/Oracle/Middleware/user_projects/domains/KerberosDomain/krb5libs.log
 kdc = FILE=/root/Oracle/Middleware/user_projects/domains/KerberosDomain/krb5kdc.log
 admin_server = FILE=/root/Oracle/Middleware/user_projects/domains/KerberosDomain/kadmind.log


[libdefaults]
 default_realm = KERBEROSSSO.COM
 dns_lookup_realm = false
 dns_lookup_kdc = false
 default_tkt_enctypes = des-cbc-crc
 default_tgs_enctypes = des-cbc-crc
 ticket_lifetime = 600


[realms]
 KERBEROSSSO.COM = {
  kdc = 192.168.0.100:88
  admin_server = win2003
  default_domain = KERBEROSSSO.COM
 }


[domain_realm]
 .kerberossso.com = KERBEROSSSO.COM


[appdefaults]
 autologin = true
 forward = true
 forwardable = true
 encrypt = true


 a3. Save the krb5.conf
 a4. Copy the keytab file, wlshost.keytab, (generated on step III) to the WLS domain root folder, KerberosDomain
 a5. Run the following command to test the keytab and generate a cache for the kerberos ticket:

 kinit -V -k -t /root/Oracle/Middleware/user_projects/domains/KerberosDomain/wlshost.keytab HTTP/wlshost@KERBEROSSSO.COM

 a6. You should see a message like:

 Authenticated to Kerberos v5





 a7. Kerberos keytab and configuration works fine and a ticket was cached in your machine. To see the cached tickets, you can run the following command:

 klist

 a8. If everything went well, you should see something like:




V. Configuring WLS to access the KDC


a. Move the /etc/krb5.conf to your domain's root folder (/root/Oracle/Middleware/user_projects/domains/KerberosDomain/)
b. Create a JAAS loging file in the Domain's root folder (jaas.login) with the following contents:


com.sun.security.jgss.initiate {


     com.sun.security.auth.module.Krb5LoginModule required
     principal="HTTP/wlshost@KERBEROSSSO.COM"
     useKeyTab=true
     keyTab="/root/Oracle/Middleware/user_projects/domains/KerberosDomain/wlshost.keytab"
     storeKey=true
     useTicketCache=true
     doNotPrompt=true
     debug=true;
};


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


     com.sun.security.auth.module.Krb5LoginModule required
     principal="HTTP/wlshost@KERBEROSSSO.COM"
     useKeyTab=true
     keyTab="/root/Oracle/Middleware/user_projects/domains/KerberosDomain/wlshost.keytab"
     storeKey=true
     useTicketCache=true
     doNotPrompt=true
     debug=true;


};


c. Note: Available options for jaas.login:


Debug: true/false
storeKey: true/false 
useTicketCache: true/false 
useKeyTab: true/false 
doNotPrompt: true/false 
isInitiator: true/false 
KeyTab: <PATH_TO_KEYTAB> 
refreshKrb5Config: true/false 
principal: <SPN> 
tryFirstPass: true/false 
useFirstPass: true/false 
storePass: true/false 
clearPass: true/false


d. Your domain root folder (/root/Oracle/Middleware/user_projects/domains/KerberosDomain/) should now contain:
c1. wlshost.keytab
c2. jaas.login
c3. krb5.conf

e. Edit your startWeblogic.sh script to add the following parameters to your JAVA_OPTION variable:


-Dsun.security.krb5.debug=true 
-Dweblogic.security.enableNegotiate=true 
-Djavax.security.auth.useSubjectCredsOnly=false 
-Djava.security.auth.login.config=/root/Oracle/Middleware/user_projects/domains/KerberosDomain/jaas.login 
-Djava.security.krb5.conf=/root/Oracle/Middleware/user_projects/domains/KerberosDomain/krb5.conf


f. Startup WLS and go to Security Realm / myrealm / Providers / Authentication
g. Create a new "Negotiate Identity Asserter" provider, and give it a name.
h. Click on the recently created Negotiate Identity Assertion provider and go to Configuration / Provider Specific and uncheck "Form Based Negotiation Enabled"
i. Restart WLS


VI. Configuring Application and User to access protected resources


(If your WLS has users and groups imported from an AD Provider, skip next step)
a. In WLS Admin Console, go to Security Realm / myrealm / Users and Groups and create a user called wlsuser3. Set a password.
b. Check/edit the web.xml and weblogic.xml from the provided application (check the end of this post)


web.xml:


<?xml version='1.0' encoding='UTF-8'?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<welcome-file-list>
<welcome-file>welcome.html</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>Constraint-0</display-name>
<web-resource-collection>
<web-resource-name>BasicSecureApp</web-resource-name>
<url-pattern>/secured/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</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>
<role-name>SSOrole</role-name>
</security-role>
</web-app>


weblogic.xml:


<?xml version='1.0' encoding='UTF-8'?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<security-role-assignment>
<role-name>SSOrole</role-name>
<principal-name>wlsuser3</principal-name>    
</security-role-assignment>
</weblogic-web-app>


c. Update the web.xml and weblogic.xml to the provided war (you can use winzip, 7zip or winrar to open, edit and update the files to the WAR).


d. Deploy the provided application to WLS.


VII. Configuring the IE for Integrated Windows Authentication


a. In Internet Explorer, select Tools  Internet Options.
a1. Select the Security tab.
a2. Select Local intranet and click Sites.
a3. In the Local intranet popup, ensure that the "Include all sites that bypass the proxy server" and "Include all local (intranet) sites not listed in other zones" options are checked.
a4. Click Advanced.
a5. In the Local intranet (Advanced) dialog box, add all relative domain names that will be used for WebLogic Server instances participating in the SSO configuration (for example, wlshost) and click OK.


b. Configure Intranet Authentication
b1. Select Tools  Internet Options.
b2. Select the Security tab.
b3. Select Local intranet and click Custom Level....
b4. In the Security Settings dialog box, scroll to the User Authentication section.
b5. Select "Automatic logon only in Intranet zone". This option prevents users from having to re-enter logon credentials, which is a key piece to this solution.
b6. Click OK.


c. Verify the Proxy Settings


c1. If you have a proxy server enabled:
c2. Select Tools  Internet Options.
c3. Select the Connections tab and click LAN Settings.
c4. Verify that the proxy server address and port number are correct.
c5. Click Advanced.
c6. In the Proxy Settings dialog box, ensure that all desired domain names are entered in the Exceptions field.
c7. Click OK to close the Proxy Settings dialog box.


VIII. Does it work?


With the application deployed and IE configurations done, go to http://wlshost:7001/BasicSecureApp/index.jsp or whatever name you have to your host/port.




IX. Things to check


a. Check the KDC, client and WLS clocks. They must be synchronized in order to KDC grants a ticket.


b. If you're using Windows 2008 Server, by default, it does not support DES encryption. Check http://technet.microsoft.com/en-us/library/dd560670%28WS.10%29.aspx


c. Check the Kerberos debug information, it should be printed to the WLS sdtout if you set debug true in the jaas.login file.




X. Files


BasicSecureApp

jaas.login

krb5.conf




XI. Reference and Documentation


a. kinit reference
http://linux.die.net/man/1/kinit


b. klist reference
http://linux.die.net/man/1/klist


c. kdestroy reference
http://linux.die.net/man/1/kdestroy


d. Configuring SSO with Microsoft Clients
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/secmanage/sso.html


e. krb5.config Options
http://linux.die.net/man/5/krb5.conf


f. setspn
http://technet.microsoft.com/en-us/library/cc773257(WS.10).aspx


g. ktpass
http://technet.microsoft.com/en-us/library/cc753771(WS.10).aspx


h. JAAS login file configuration options
http://download.oracle.com/javase/1.4.2/docs/guide/security/jaas/tutorials/LoginConfigFile.html


i. WLs 10.3.4 
http://download.oracle.com/docs/cd/E17904_01/web.1111/e13707/sso.htm#i1106670


http://download.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html 

6 comments:

  1. Hi Paulo, thanks for uploading the SSO configuration steps using Kerberos. We followed all the steps you mentioned and on hitting "http://:/BasicSecureApp" url, we are getting the welcome page. Wanted to know what signifies that authentication happened and was done successfully. Thanks, Nitin.

    ReplyDelete
  2. Hi Nitin. The welcome page (welcome.html) is not secured, meaning, you're not authenticated yet. The authentication should only happens when you click on the "Access Protected Page" link.
    You can enable the debug flags:
    weblogic - security - atn and atz to see the authentiaction process

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Hi Paulo, thanks for this post, is very straightforward and help me to realize a lot of mistakes i made when reading the Oracle guide on the issue.

    I've followed your post but i get no authentication at all. I tried with:

    ktpass -princ HTTP/wlshost.mytest.com@MYTEST.COM -pass Letmein123 -mapuser wlshost -mapOp set -DesOnly -crypto DES-CBC-CRC -pType KRB5_NT_PRINCIPAL -SetPass -out wlshost.keytab

    and i do not get even a SPNEGO token, i have to generate the keytab without the WLS FQDN like this:

    ktpass -princ HTTP/wlshost@MYTEST.COM -pass Letmein123 -mapuser wlshost -mapOp set -DesOnly -crypto DES-CBC-CRC -pType KRB5_NT_PRINCIPAL -SetPass -out wlshost.keytab

    But then i got this on my log:


    <acceptGssInitContextToken failed
    com.bea.security.utils.kerberos.KerberosException: No valid credentials provided (Mechanism level: Failed to find any Kerberos Key)
    ....
    Caused By: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos Key)

    This is my jaas.login:

    com.sun.security.jgss.krb5.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    principal="HTTP/wlshost@MYTEST.COM" useKeyTab=true keyTab="/home/oracle/wlshost.keytab" storeKey=true useTicketCache=true doNotPrompt=true debug=true;
    };
    com.sun.security.jgss.krb5.accept {
    com.sun.security.auth.module.Krb5LoginModule required
    principal="HTTP/wlshost@MYTEST.COM" useKeyTab=true keyTab="/home/oracle/wlshost.keytab" storeKey=true useTicketCache=true doNotPrompt=true debug=true;
    };

    This is my krb

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

    [libdefaults]
    default_realm = MYTEST.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false
    default_tkt_enctypes = des-cbc-crc
    default_tgs_enctypes = des-cbc-crc
    ticket_lifetime = 600
    forwardable = yes

    [realms]
    MYTEST.COM = {
    kdc = 10.0.2.15:88
    admin_server = kdcserver
    default_domain = MYTEST.COM
    }

    [domain_realm]
    .mytest.com = MYTEST.COM

    [appdefaults]
    autologin = true
    forward = true
    forwardable = true
    encrypt = true


    i reviewed every step to see where is the mistake, but with no luck, i would appreciate your comments or help.

    ReplyDelete
  5. In step IV. Configuring the WLS Machine to access the KDC, what do you get when you run

    kinit -V -k -t /root/Oracle/Middleware/user_projects/domains/KerberosDomain/wlshost.keytab HTTP/wlshost@KERBEROSSSO.COM

    This is a test to check if the ticket was generated correctly and cached in your server's machine.

    Also, what do you get in your server's machine when you do a klist command?

    ReplyDelete
  6. Hi

    when I followed the instructions provided
    when kinit was executed got the following
    kinit(v5): Client not found in Kerberos database while getting initial credentials

    do you have any idea

    ReplyDelete