Configuring Kerberos authentication in WebSphere Application Server Community Edition

Kerberos authentication is not currently supported in WebSphere® Application Server Community Edition. In this article, we highlight how you can leverage the IBM® Java™ Platform provided Kerberos implementation to perform Kerberos authentication in WebSphere Application Server Community Edition.

Ashish Jain, Software Engineer, IBM

Author photoAshish Jain is a Software Engineer at IBM India Software Labs in Bangalore India. He is working as Level 3 Technical Support of IBM WebSphere Application Server Community Edition. He received a Bachelors of Engineering in Computer Science from NITK Surathkal, India and joined IBM in 2005 as an ELTP.


developerWorks Contributing author
        level

Vamsavardhana Reddy Chillakuru (vamsic007@in.ibm.com), Advisory Software Engineer, EMC

Author photoVamsavardhana Reddy Chillakuru (a.k.a Vamsi) is an Advisory Software Engineer at IBM India Software Labs in Bangalore, India. He is a committer on Apache Geronimo and Apache Tuscany projects, a member of the Apache Geronimo Project Management Committee, and is part of the IBM WebSphere Application Server Community Edition Level 3 Support Team. He received his Bachelor of Statistics (Hons.) and Master of Statistics degrees from the Indian Statistical Institute, Kolkata, India in the years 1994 and 1996, respectively.


developerWorks Contributing author
        level

21 October 2009

Also available in Chinese Spanish

Introduction

IBM WebSphere Application Server Community Edition V2.1.1.2 (hereafter called Community Edition) is a free-to-use Java Platform, Enterprise Edition 5.0 (Java EE 5) certified application server based on Apache Geronimo 2.1.4. Community Edition uses Java Authentication and Authorization Service (JAAS) login modules for user authentication in Web applications, and Java Authorization Contract for Containers (JACC) for authorization.

Kerberos is an authentication protocol developed by the Massachusetts Institute of Technology. Kerberos protocol allows computer nodes communicating on a non-secure computer network to authenticate each other in a secure manner. The latest version of the Kerberos protocol is Version 5.

Community Edition does not provide a Kerberos protocol implementation. In this article, you will leverage the Kerberos protocol implementation provided by the IBM Java Platform to authenticate and authorize users in Community Edition. For the purpose of this article, we use a Microsoft® Active Directory server (hereafter called Active Directory) as a user repository. This article requires WebSphere Application Server Community Edition V2.1.1.2 or later.


Kerberos: How it works

Kerberos uses symmetric key cryptography and requires a trusted third party called the Key Distribution Center (KDC) consisting of an Authentication Server (AS) and a Ticket Granting Server (TGS). The KDC maintains a database of secret keys. Each entity, either a user or a service, on the network shares a secret key with the KDC and the secret key is known only to the KDC and the entity itself. Thus the knowledge of this secret key provides identification of the entity. Kerberos uses tickets, referred to as Kerberos tickets, which are time stamped and short-lived. Therefore, it is important for the entities to maintain synchronized time.

An entity authenticates itself to the Authentication Server using a shared secret, typically a password, and receives a Ticket Granting Ticket (TGT). It then contacts the Ticket Granting Server, uses the TGT to prove its identity, and asks for a service. The TGS verifies if the entity is authorized to use the service and sends a Service Ticket (ST). The entity then contacts the Service Server (SS), uses the ST to prove that it has been authorized to avail the service and avails the service. The entity can reuse the TGT to get additional STs for use with SS without having to authenticate itself with AS once again. The Kerberos protocol is devised such that the authentication happens without the shared secret (for example, the password) getting transmitted on the network. When using Kerberos authentication, users typically enter their credentials using an input device like a keyboard, whereas services use a Keytab file to store and use their credentials to authenticate to the KDC.


Kerberos and Community Edition

Community Edition does not provide an implementation of the Kerberos protocol. The IBM Java Platform provides an implementation of the Kerberos protocol through the com.ibm.security.auth.module.Krb5LoginModule class. To leverage the Java Platform provided Kerberos implementation, we have created a LoginModule implementation that wraps the Krb5LoginModule and delegates all LoginModule API invocations to Krb5LoginModule. The code for the KerberosLoginModule is shown in Listing 1.

Listing 1. KerberosLoginModule.java
package org.apache.geronimo.security.realm.providers;

import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class KerberosLoginModule implements LoginModule {

    private static Log log = LogFactory.getLog(KerberosLoginModule.class);
    private Subject subject;
    private LoginModule krb5LoginModule;
    private Subject krb5Subject;
    private Principal addOnPrincipal;

    public void initialize(Subject subject, CallbackHandler callbackHandler,
 Map sharedState, Map options) {
        this.subject = subject;
        String krb5LoginModuleClass = (String) options.get("krb5LoginModuleClass");
        try {
            krb5LoginModule = (LoginModule)Class.forName(krb5LoginModuleClass)
.newInstance();
        } catch (Exception e) {
            log.error("Initialization failed", e);
            throw new IllegalArgumentException("Unable to configure 
kerberos login module: " + e.getMessage(),e);
        }
        
        Map options1 = new HashMap();
        for(Object key : options.keySet()) {
            String key1 = (String) key;
            if(key1.startsWith("krb_")) {
                options1.put(key1.substring(4), options.get(key1));
            }
        }
        
        krb5Subject = new Subject();
krb5LoginModule.initialize(krb5Subject, callbackHandler, sharedState,
options1);
String addOnPrincipalClass = (String) options.get("addOnPrincipalClass");
String addOnPrincipalName = (String) options.get("addOnPrincipalName");
if(addOnPrincipalClass != null && !addOnPrincipalClass.equals("")) {
   try {
   addOnPrincipal = (Principal) Class.forName(addOnPrincipalClass).getConstructor
    (String.class).newInstance(addOnPrincipalName);
            } catch (Exception e) {
             log.error("Initialization failed", e);
             throw new IllegalArgumentException("Unable to configure kerberos login 
              module: " + e.getMessage(), e);
            }
        }
    }

    public boolean login() throws LoginException {
        return krb5LoginModule.login();
    }

    public boolean commit() throws LoginException {
        boolean result = krb5LoginModule.commit();
        if(result) {
         if(addOnPrincipal != null) subject.getPrincipals().add(addOnPrincipal);

subject.getPrincipals().addAll(krb5Subject.getPrincipals());
       subject.getPublicCredentials().addAll(krb5Subject.getPublicCredentials());
       subject.getPrivateCredentials().addAll(krb5Subject.getPrivateCredentials());
        }
        return result;
    }

public boolean abort() throws LoginException {
        return krb5LoginModule.abort();
    }

public boolean logout() throws LoginException {
    if(!subject.isReadOnly()) {
    // Remove principals and credentials added by this LoginModule
    if(addOnPrincipal != null) subject.getPrincipals().remove(addOnPrincipal);
subject.getPrincipals().removeAll(krb5Subject.getPrincipals());
    subject.getPublicCredentials().removeAll(krb5Subject.getPublicCredentials());
   subject.getPrivateCredentials().removeAll(krb5Subject.getPrivateCredentials());
        }
        return krb5LoginModule.logout();
    }
}

The KerberosLoginModule has the following LoginModule options:

  • krb5LoginModuleClass: Specifies the fully qualified name of the Kerberos protocol implementation class provided by the Java Platform. This class must implement the javax.security.auth.spi.LoginModule interface. Since we will be using the IBM Java Platform provided Krb5LoginModule, this value will be com.ibm.security.auth.module.Krb5LoginModule.
  • addOnPrincipalClass: Specifies the fully qualified name of the class of the principal to be added to the subject if the login succeeds. This principal will be added to the subject in addition to any principals that result from logging in using the krb5LoginModuleClass. Do not use this option if you are not adding more principals.
  • addOnPrincipalName: Specifies the name of the principal to be added to the subject. This option is used only if an addOnPrincipalClass is specified.
  • krb_*: Any options that are passed on to the initialize() method of krb5LoginModuleClass must be specified using a prefix of “krb_”. The prefix “krb_” will be removed from the option name before it is passed on to the initialize() method. For example, krb_debug=true will be passed on as debug=true to the initialize() method.

The KerberosLoginModule.initialize() method creates an instance of class configured using the krb5LoginModuleClass option and initializes that instance with only those options whose name starts with “krb_”, but with that prefix removed from the option name. It also creates an add-on principal as configured by the addOnPrincipalClass and addOnPrincipalName options. Upon successful authentication, the KerberosLoginModule.commit() method adds all Principals, Public Credentials, and Private Credentials resulting from the login of the krb5LoginModuleClass and the add-on Principal to the Subject. The KerberosLoginModule class is used for creating security realms that perform authentication in Community Edition using the Kerberos protocol.


Setting up users in Microsoft Active Directory

Installing and configuring Microsoft Active Directory server is out of the scope of this article. As per our configuration, we have started the Key Distribution Centre (KDC) on port 88. Follow the steps below to add new users to the Active Directory server.

  1. Launch Active Directory Users and Computers and select Users as shown in Figure1.
    Figure 1. Active Directory users and computers
    Active Directory users and computers
  2. Right-click Users and select New > User as shown in Figure 2.
    Figure 2. Create new user
    Create new user
  3. In the dialog box, fill the First Name, Last Name, and User logon name and click Next as shown in Figure 3.
    Figure 3. Create new user – User details
    Create new user – User details
  4. Enter a password for the user and click Next as shown in Figure 4.
    Figure 4. Create new user - Password
    Create new user - Password
  5. Click Finish to complete adding new user as shown in Figure 5.
    Figure 5. Create new user – New user added
    Create new user – New user added

You can observe that the newly created user is listed under "Users".


Setting up the client machine

This step requires copying the Kerberos configuration file to a pre-defined location. In Windows client, this file is called "krb5.ini" and is present in "C:/winnt/". For Linux clients, this file is called "krb5.conf" and is present in "/etc". The Kerberos configuration file we have used in our setup is shown in Listing 2.

Listing 2. Kerberos configuration file - krb5.ini
[libdefaults]
default_realm = AUSTIN.IBM.COM
default_tkt_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc
default_tgs_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc

[realms]
AUSTIN.IBM.COM = {
 		kdc = ad1ldap.austin.ibm.com:88
}

[domain_realm]
austin.ibm.com = AUSTIN.IBM.COM
.austin.ibm.com = AUSTIN.IBM.COM

Let us now look at each of the sections and entries in this configuration file.

The first section is [libdefaults], which details the default values used by the Kerberos V5 library. The different fields in this section are described as follows:

  • default_realm: This is the default realm to be used in communication between a client and host. If you use a principal name of "ashish", AUSTIN.IBM.COM will be appended by the default to the principal and the final principal will be ashish@AUSTIN.IBM.COM.
  • default_tgs_enctypes: This field identifies the session key encryptions that are returned by KDC. Make sure that you specify rc4-hmac in this field while using the Microsoft Active Directory as the KDC.
  • default_tkt_enctypes: This field identifies the list of session key encryption types that will be requested by the client.

The second section is [realms], which details the realm and the KDC server mapping. In Listing 2, AUSTIN.IBM.COM has been mapped to ad1ldap.austin.ibm.com:88. Here, ad1ldap.austin.ibm.com is the hostName and 88 is the port on which KDC server is running.

The third section is [domain_realm], which details the mapping of subdomains and domain names to the Kerberos realm names. This determines what realm a host is in, given its fully qualified domain name.


Adding custom Kerberos login module JAR to the repository

The current version of Community Edition does not have an implementation of KerberosLoginModule. This article provides a custom login module JAR containing the KerberosLoginModule class (shown in Listing 1), which will help you to create a Kerberos security realm in Community Edition. This jar needs to be added to the Community Edition repository. Follow the steps below to add the login module jar to the Community Edition repository:

  1. Start Community Edition, and open http://localhost:8080/console/ in your browser.
  2. Enter system for the user name and manager for the password. Click Login, which brings up the Welcome page in the administrative console as shown in Figure 6.
    Figure 6. Administrative console – Welcome page
    Administrative console – Welcome page
  3. Click Repository under Console Navigation to launch the Repository portlet shown in Figure 7.
    Figure 7. Repository portlet
    Repository portlet
  4. Browse to the location where you have downloaded the custom login module jar. Name the fields as shown in Figure 7 and click Install. This installs the login module jar to the Community Edition repository.

Creating a Kerberos realm

This section will describe the steps to create a Kerberos realm using the Community Edition Administrative Console. Follow the steps below to create a Kerberos realm:

  1. Click the Security Realms link in Console Navigation under Security as shown in Figure 8.
    Figure 8. Launching the security realms portlet
    Launching the security realms portlet
  2. In the Security Realms portlet, click Add new security realm as shown in Figure 9.
    Figure 9. Launching the new security realm page
    Launching the new security realm page
  3. On the next page, name the realm as kerberos-realm and select realm type as Other and click Next as shown in Figure 10.
    Figure 10. Creating the new security realm
    Creating the new security realm
  4. Fill the forms as shown in Figure 11. Select the login module jar from drop down box. This is the same jar that has been added to the repository earlier. Name the Login Module Class as org.apache.geronimo.security.realm.providers.KerberosLoginModule. Add the Configuration options as shown in Listing 3.
    Listing 3. Configuration options while creating the security realm
    addOnPrincipalName=admin
    addOnPrincipalClass=org.apache.geronimo.security.realm.providers.
    GeronimoGroupPrincipal
    krb_debug=true
    krb5LoginModuleClass= com.ibm.security.auth.module.Krb5LoginModule
    Figure 11. Creating the new security realm - configuration
    Creating the new security realm - configuration
  5. Once done, you can browse to the bottom of the page. You can click Show Plan, as shown Figure 12, to see the Kerberos realm plan.
    Figure 12. Displaying the created security realm plan
    Displaying the created security realm plan
  6. On the next screen, you can find the plan you have created displayed in a text box as shown in Figure 13. You can also copy it for your reference. Click Deploy to deploy the security realm to Community Edition.
    Figure 13. Deploying the security realm plan
    Deploying the security realm plan
    On successful deployment, you can see "kerberos-realm" listed in the Security Realms page as shown in Figure 14.
    Figure 14. Successful deployment of the Kerberos realm
    Successful deployment of the Kerberos realm

Deploying and testing the sample application

To test the Kerberos realm, we have provided a sample application with this article. Follow the steps below to deploy and test this sample application:

  1. Click Deploy New in console navigation under Applications as show in Figure 15.
    Figure 15. Launching the deploy new portlet
    Launching the deploy new portlet
  2. Browse to the location where you have downloaded the sample application. Select SimpleWebApp-Subject.war against the Archive and SimpleWebApp-Subject-plan.xml against the Plan as shown in Figure 16.
    Figure 16. Installing the application
    Installing the application
  3. Click Install to deploy the sample application.
  4. Once done, launch the url http://localhost:8080/kerberos-realm-demo/admin/admin.jsp. This shows a screen to provide login credentials (Figure 17).
    Figure 17. Simple Web App – Login screen
    Simple Web App – Login screen
  5. Enter the user name and password earlier created with Microsoft Active Directory and click Login.
  6. On successful authentication, you can see a welcome page, which lists that the principal ashishjain@AUSTIN.IBM.COM has been added to the admin group. It also lists the generated Kerberos ticket as shown in Figure 18.
    Figure 18. Welcome page and other artifacts on successful authentication
    Welcome page and other artifacts on successful authentication

    Notice that in addition to the KerberosPrincipal, the Subject also has GeronimoGroupPrincipal configured in the realm using the addOnPrincipal options.

  7. Now try with a wrong password and you will see a login failure message as shown in Figure 19.
    Figure 19. Result of login failure
    Result of login failure

Conclusion

This article showed how you can leverage the IBM Java Platform provided Kerberos protocol implementation by creating a KerberosLoginModule wrapper to authenticate users in Community Edition. It also demonstrated, with a sample Web application, authenticating users listed in a Microsoft Active Directory server using Kerberos.


Download

DescriptionNameSize
Code sampleapplication_files.zip10 KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Open source
ArticleID=438292
ArticleTitle=Configuring Kerberos authentication in WebSphere Application Server Community Edition
publish-date=10212009