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 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.LoginModuleinterface. Since we will be using the IBM Java Platform provided Krb5LoginModule, this value will becom.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 theinitialize()method. For example,krb_debug=truewill be passed on asdebug=trueto theinitialize()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.
- Launch Active Directory Users and Computers and select
Users as shown in Figure1.
Figure 1. Active Directory users and computers
- Right-click Users and select New > User as shown
in Figure 2.
Figure 2. Create new user
- 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
- Enter a password for the user and click Next as shown in
Figure 4.
Figure 4. Create new user - Password
- Click Finish to complete adding new user as shown in Figure 5.
Figure 5. Create new user – New user added
You can observe that the newly created user is listed under "Users".
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:
- Start Community Edition, and open http://localhost:8080/console/ in your browser.
- Enter
systemfor the user name andmanagerfor 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
- Click Repository under Console Navigation to launch the
Repository portlet shown in Figure 7.
Figure 7. Repository portlet
- 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.
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:
- Click the Security Realms link in Console Navigation under
Security as shown in Figure 8.
Figure 8. Launching the security realms portlet
- In the Security Realms portlet, click Add new security realm
as shown in Figure 9.
Figure 9. Launching the new security realm page
- On the next page, name the realm as
kerberos-realmand select realm type as Other and click Next as shown in Figure 10.
Figure 10. Creating the new security realm
- 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 realmaddOnPrincipalName=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
- 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
- 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
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
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:
- Click Deploy New in console navigation under Applications as
show in Figure 15.
Figure 15. Launching the deploy new portlet
- 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
- Click Install to deploy the sample application.
- 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
- Enter the user name and password earlier created with Microsoft Active Directory and click Login.
- 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
Notice that in addition to the KerberosPrincipal, the Subject also has GeronimoGroupPrincipal configured in the realm using the addOnPrincipal options.
- 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
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.
| Description | Name | Size | Download method |
|---|---|---|---|
| Code sample | application_files.zip | 10 KB | HTTP |
Information about download methods
Learn
-
MIT Kerberos
-
IBM JDK Krb5 LoginModule
-
Kerberos Credentials Acquisition and Management
-
WebSphere Application Server Community Edition support site
-
WebSphere Application Server Community Edition documentation
-
WebSphere Application Server Community Edition samples
-
Apache Geronimo site
-
Develop applications on all the Java EE5 APIs
-
Get to know Java EE 5
-
Apache Geronimo samples
-
WebSphere Application Server Community Edition Technical Support offerings
Get products and technologies
Discuss

Ashish 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.

Vamsavardhana 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.
Comments (Undergoing maintenance)





