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

Difference between revisions of "Stardust/Knowledge Base/Security/Single Sign-on/SSO using JAAS and GSS API with Apache DS and Kerberos"

m
Line 163: Line 163:
 
Now you can run the server side with Server class’s main method. Note that before your run Server, Apache DS must be running and required user and service/server SPN must be created as mentioned above. <br>If server is started successfully, you can run the client side, Client1 class here, and see that initSecContext method on GSSContext goes fine. This means user authentication details have been securely communicated to the server and it has accepted the credentials. Meaning SSO has taken place. That is user has been authenticated by server without asking end user its credentials and without passing the user credentials across network. Here security context is established means, user has been authenticated and appropriate cryptographic keys have been made between client and server. These keys are available in GSSContext and you can use this context’s high level methods to encrypt and decrypt the messages for secure communication between client and server.<br>Now, once authentication has taken place and security context is created, client can securely communicate with server by using encrypting the messages and sending then over to server using normal URL or Form parameters over HTTP. This is end-to-end security as opposed to point to point security offered by HTTPS. Here we attach the encrypted message to URL, which server side will extract like normal URL parameter and decrypt is using already shared keys, using GSSContext at server side. Here we have used Base 64 encoding to convert encrypted message into URL safe format. Also you will see at server side this URL parameter is first decoded using Base 64 and then decrypted using GSSContext.<br>
 
Now you can run the server side with Server class’s main method. Note that before your run Server, Apache DS must be running and required user and service/server SPN must be created as mentioned above. <br>If server is started successfully, you can run the client side, Client1 class here, and see that initSecContext method on GSSContext goes fine. This means user authentication details have been securely communicated to the server and it has accepted the credentials. Meaning SSO has taken place. That is user has been authenticated by server without asking end user its credentials and without passing the user credentials across network. Here security context is established means, user has been authenticated and appropriate cryptographic keys have been made between client and server. These keys are available in GSSContext and you can use this context’s high level methods to encrypt and decrypt the messages for secure communication between client and server.<br>Now, once authentication has taken place and security context is created, client can securely communicate with server by using encrypting the messages and sending then over to server using normal URL or Form parameters over HTTP. This is end-to-end security as opposed to point to point security offered by HTTPS. Here we attach the encrypted message to URL, which server side will extract like normal URL parameter and decrypt is using already shared keys, using GSSContext at server side. Here we have used Base 64 encoding to convert encrypted message into URL safe format. Also you will see at server side this URL parameter is first decoded using Base 64 and then decrypted using GSSContext.<br>
  
== References ==
+
== References ==
  
Zipped Source Code
+
1.&nbsp;The java source code, properties files, ldif and config files discussed in this article are enclosed here;&nbsp;
  
&nbsp;
+
[http://wiki.eclipse.org/images/9/91/SSO_Example_Source.zip SSO_Example_Source.zip]&nbsp;([http://wiki.eclipse.org/images/9/91/SSO_Example_Source.zip http://wiki.eclipse.org/images/9/91/SSO_Example_Source.zip])
 +
 
 +
2.&nbsp;[http://www.ibm.com/developerworks/java/library/j-gss-sso/ http://www.ibm.com/developerworks/java/library/j-gss-sso/], by Faheem Khan
 +
 
 +
3.&nbsp;[http://thejavamonkey.blogspot.com/2008/07/using-apache-directory-server-as-kdc.html http://thejavamonkey.blogspot.com/2008/07/using-apache-directory-server-as-kdc.html], for setting Apache DS as KDC

Revision as of 09:15, 2 November 2011

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

 

Writing the Server Part

  Here I have implemented the server part as simple JAX-RS web service using CXF. You may take the core idea form here and implement the server part as per your requirement like Servlet Filter or SOAP handler or as any component that fits your need.

Server Class:

This class exposes the EchoService class as JAX-RS service at URL http://localhost:9000/

Fig1:

Stardust server class.jpg

EchoService Class:

This class is part of our example business service layer. It will just extract the authentication details, Kerberos token in this case, from incoming request and verify it with already initialized server context using utility class called GSSServer. If verification fails, it throws the security exception. Note the usage of Base 64 encoding and decoding to avoid sending raw Kerberos tokens and URL sage messages across client and server.


GSS Server Properties:

 KDC and other properties are store as part of gssserver.properties file as shown below. It is used to store location of KDC server, realm/domain, and JAAS config details.


JAAS Config File:

The JAAS conf file for client and server side details looks like following;



GSSServer Class:

This class is initialized during service creation. It abstracts out the authentication and communication with KDC server using JAAS and GSS API. This class uses the server properties mentioned above to initialize the security context. Later on when, client request comes in, client’s Kerberos token will be validated against this security context. Note the usage of GSSContext class which is part of GSS API to authenticate the client’s Kerberos token and encrypt (wrap method) and decrypt (unwrap method) the messages between client and server. Initialized GSSContext will have the required keys for given client.


 

How Client Side Looks Like

Like server side, at client site I have used utility class, GSSClient, which abstracts out the communication with KDC.


Client Class:

The client class uses the GSSClient class to pass username and password to authenticate the user and get the Kerberos token (service ticket for given server). Note that token is in byte array format. So we used Base 64 encoding to convert it into string and then we simply add it as part of authentication header. That’s it there in client. So, actual stuff happens in GSSClient which is discussed next;

 

Client Side Properties:

The client side properties are stored as part of gssclient.properties file. It contains the server SPN, KDC Server Address, realm/domain, and JAAS properties. 


GSSClient Class:

This class uses the JAAS and GSS API to authenticate and create security context against given KDC. Once client initializes the security context, it can be used for SSO and secure communication with given server.
Here KDC details are loaded from gssclient.properties file. Note how client uses the initialized security context to ext

 

Summary

Now you can run the server side with Server class’s main method. Note that before your run Server, Apache DS must be running and required user and service/server SPN must be created as mentioned above.
If server is started successfully, you can run the client side, Client1 class here, and see that initSecContext method on GSSContext goes fine. This means user authentication details have been securely communicated to the server and it has accepted the credentials. Meaning SSO has taken place. That is user has been authenticated by server without asking end user its credentials and without passing the user credentials across network. Here security context is established means, user has been authenticated and appropriate cryptographic keys have been made between client and server. These keys are available in GSSContext and you can use this context’s high level methods to encrypt and decrypt the messages for secure communication between client and server.
Now, once authentication has taken place and security context is created, client can securely communicate with server by using encrypting the messages and sending then over to server using normal URL or Form parameters over HTTP. This is end-to-end security as opposed to point to point security offered by HTTPS. Here we attach the encrypted message to URL, which server side will extract like normal URL parameter and decrypt is using already shared keys, using GSSContext at server side. Here we have used Base 64 encoding to convert encrypted message into URL safe format. Also you will see at server side this URL parameter is first decoded using Base 64 and then decrypted using GSSContext.

References

1. The java source code, properties files, ldif and config files discussed in this article are enclosed here; 

SSO_Example_Source.zip (http://wiki.eclipse.org/images/9/91/SSO_Example_Source.zip)

2. http://www.ibm.com/developerworks/java/library/j-gss-sso/, by Faheem Khan

3. http://thejavamonkey.blogspot.com/2008/07/using-apache-directory-server-as-kdc.html, for setting Apache DS as KDC

Back to the top