Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Stardust/Knowledge Base/Security/Single Sign-on/SSO using JAAS and GSS API with Apache DS and Kerberos

Implementing SSO using JAAS and GSS API with Apache DS and Kerberos

Introduction:

This tutorial explains what Kerberos protocol is and how it works at large. Then we will see how to implement SSO (Single Sign On) and secure communication using Kerberos. This tutorial will use the Apache DS 1.5.7 and simple Web Service application to demonstrate the SSO. I will use some java security APIs like JAAS and Java GSS (Generic Security Services). It is assumed that you know and understand how these technologies work.

What is Kerberos and how it works?

Kerberos is a network authentication protocol developed by Internet Engineering Task Force and has been wide adopted by both Java and .Net communities. This protocol doesn’t require that user password be sent over network for authentication.
Here is how Kerberos protocol works;
Consider there are two systems S1 and S2, which leverage the SSO and secure communication with Kerberos protocol. That means if user U1 is logged into S1, and S1 needs to talk to S2 for fulfilling user request, then user must not be prompted for authentication again but still, S2 must make sure that the user is one who says he is. Means S2 should authenticate the user seamlessly, without user being aware of it. Let’s see how SSO and secure communication works between S1 and S2;

  1. The user U1 logs into S1 with his/her credentials; typically username and password.
  2. S1 request the Kerberos ticket form KDC (Key Distribution Center) by sending username only.
  3. The KDC issues an encrypted ticket containing session key. The ticket is encrypted by using key derived from user’s password. This ticket is called as TGT (Ticket Granting Ticket). Note that, although user password is not required for requesting TGT, password is required to decrypt it and fetch the session key in it. Without user password TGT is of no use. 
  4. S1 uses user’s password to decrypt the TGT and fetch session key from it and requests one more ticket from KDC for communication with S2.
    Note that users and systems/services (like U1 and S2 here) must be registered with KDC prior.
  5. Now KDC creates a ticket called as Service Ticket and add the user’s authentication data and a new key called as sub-session key in it. The KDC encrypts the service ticket by key generated from S2’s password. Then, the KDC creates a message, adds encrypted service ticket and sub-session key in it and encrypts the complete message by a key generated from user’s password and sends it back to the S1.
    Note that, now message contains the sub-session key twice, once directly in the message and then inside encrypted service ticket. The service ticket can be used only for communication between S1 and S2. This complete message can only be decrypted by the user and the enclosed encrypted service ticket can only be decrypted by S2.
  6. The S1 decrypts the message with user’s password and takes out service ticket and sub-session key.
  7. S1 sends the service ticket (which is encrypted) to S2. The S2 decrypts the service ticket and takes out U1’s authentication data and sub-session key.
    Now, S2 will trust the user’s authentication data as it could decrypt service ticket with its own password and that means it has come from KDC (which already has authenticated the user) and hence it is authentic. Hence SSO!
  8. Now, both S1 and S2 have same key (sub-session key) which they will use for secure communication with each other.

This is how SSO and secure communication is achieved using Kerberos.

Note that KDC functionality is generally implemented by directory servers like MS AD and Apache DS. For this article you may consider KDC means Apache DS.

Setting up KDC with Apache DS

Download Apache DS 1.5.7 and Apache Directory Studio 1.5.3 from Apache site and install it on your local machine. By default, it doesn’t have Kerberos service running. Follow the steps below to activate it. Note that these steps are only valid for DS version 1.5.7.

  1.  Under your Apache Directory Server install (C:\Program Files\Apache Directory Server), navigate to the folder instances\default\conf. This folder contains the config files for your server instance. server.xml is the Spring context configuration for your server, and contains the Kerberos config settings. Open this file up in a text editor.

  2.  Set the enabled property to “true” to enable the KDC. By default, it is false.

<bean id="kdcConfiguration" class="org.apache.directory.server.kerberos.kdc.KdcConfiguration">
  <!-- Whether to enable the Kerberos protocol. --> <property name="enabled" value="true" /> 
  <!-- The port to run the Kerberos protocol on. --> <property name="ipPort" value="88" /> 
  <!--<property name="searchBaseDn" value="ou=Users" />--> 
</bean>

  3.  Uncomment following bean.

<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
  <property name="name" value="keyDerivationService" />  
  <property name="interceptorClassName" value="org.apache.directory.server.core.kerberos.KeyDerivationService" />

  4. You will have to create user and service SPN in DS. You can do this using Apache Directory Studio, but the easiest way is to use LDIF file. You can use this file to define your SPN details. When you place this file at appropriate location, it would be loaded by DS on startup and it creates the specified SPNs. Now create a new .ldif file and add following content in it. It will create a user with name “monkey2” and service with name “webserver2/localhost” under example.com domain.

# Web server2 identity/service principal.
dn: uid=webserver2,ou=users,dc=example,dc=com
objectclass: top
objectclass: person
objectclass: inetOrgPerson
objectclass: krb5Principal
objectclass: krb5KDCEntry
cn: Web Server2
sn: Web Server2
uid: webserver2
userpassword: Password99
krb5PrincipalName: [mailto:webserver2/localhost@EXAMPLE.COM webserver2/localhost@EXAMPLE.COM

]# User / client2 principal.
dn: uid=monkey2,ou=users,dc=example,dc=com
objectclass: top
objectclass: person
objectclass: inetOrgPerson
objectclass: krb5Principal
objectclass: krb5KDCEntry
cn: Monkey2
sn: Monkey2
uid: monkey2
userpassword: Password100
krb5PrincipalName: [mailto:monkey2@EXAMPLE.COM monkey2@EXAMPLE.COM

]# Ticket Granting Service2.
dn: uid=krbtgt2,ou=users,dc=example,dc=com
objectclass: top
objectclass: person
objectclass: inetOrgPerson
objectclass: krb5Principal
objectclass: krb5KDCEntry
cn: KDC Service2
sn: KDC Service2
uid: krbtgt2
userpassword: randomKey
krb5PrincipalName: krbtgt2/EXAMPLE.COM@EXAMPLE.COM

  5.  Store this file under ldifDirectory directory. For location of your ldifDirectory search server.xml.

  6.  And in the end restart the DS server for changes to apply.

  7. To verify that your ldif file is loaded properly. Start the Apache Directory Studio and create new connection to your DS server with

      following details;

Hostname: localhost
Port: 10389
Encryption Method: No encryption

Authentication Method: Simple Authentication
Bind DN or user: uid=admin,ou=system
Bind password: secret

  8.  If ldif file was loaded successfully, it will have setup the client principal, the server principal, and the krbtgt service. That is, you now have a fully functioning KDC. Now you can try running your Kerberos example against the KDC.

Back to the top