Kerberos setup and JAAS configuration for running Sun JGSS tutorial against AD

If you have ever tried to follow the tutorial Advanced JGSS Security Programming, you would find out the code itself is not that complicated. However, the configuration to get a workable environment is the most intriguing part. Here is the detailed setup from my testing. Hopefully, it can save someone a few googlings.

Environment

– The KDC is provided by Windows 2003 AD.
– The domain name is ‘CORPNET.MYCORP.COM’.
– I have a service account, ‘myserviceaccount’, which was created by my AD admin and I knew the password of it.
– The service name is ‘HTTP’. In the tutorial, it was set as ‘host’. Later I will explain a bit inconvenience for me and why I had ‘HTTP’.
– The name of my laptop is ‘MYLAPTOP.corpnet.mycorp.com’. I got it with a simple ping command.
– My personal account is ‘mypersonal’. I use it everyday to login to the corporate network and as my client crendential to test those client-server application.
– My laptop is running with Windows XP SP3. All the test was done on it using JDK 1.6.0_18.

File krb5.ini

File krb5.ini was created and saved under C:\windows. It contains the following:

[libdefaults]
        default_realm = CORPNET.MYCORP.COM
        default_tkt_enctypes = rc4-hmac
        default_tgs_enctypes = rc4-hmac
[realms]
        CORPNET.MYCORP.COM  = {
               kdc = myonedomaincontroller.corpnet.mycorp.com
               default_domain = CORPNET.MYCORP.COM
}

[domain_realm]
       .CORPNET.MYCORP.COM = CORPNET.MYCORP.COM

The encryption type was obtained using MIT Kerberos for Windows utility, Network Identity Manager (details later). If you are using AD 2003 and JDK 1.6+, mostly likely the settings will work for you as well.

File jaas-krb5.conf

This is the file the tutorial was using. I have the client section set as the following:

client {
	com.sun.security.auth.module.Krb5LoginModule required
	principal="mypersonal";
};

Testing client authenticated against KDC

With above setup, when I ran the testing comand:

java -Djava.security.auth.login.config=jaas-krb5.conf Jaas client

I was asked to provide password for mypersonal and get authenticated properly.

SPN (Service Principal Name) creation

I asked my AD admin to create a SPN using the command:

setspn -A HTTP/MYLAPTOP myserviceaccount
setspn -A HTTP/mylaptop.corpnet.mycorp.com myserviceaccount

The result was that when I issued command ‘setspn -l myserviceaccount’ from my laptop, I got the following back:

Registered ServicePrincipalNames for <DN for myserviceaccount>,
    HTTP/mylaptop.corpnet.mycorp.com
    HTTP/MYLAPTOP

The reason I selected ‘HTTP’ was that I need to work on an SSO solution for my web application.

Keytab creation

I tried to use Windows ktpass command to create a keytab file from my laptop, but it did not succeed. The reason I believe is that I did not have AD admin permission to map an user account to a SPN. Besides that I already had the mapping in place thanks to my AD admin. I later found that I could use ktab.exe from JRE:

C:\jdk1.6.0_18\jre\bin> ktab.exe \ 
-a HTTP/mylaptop.corpnet.mycorp.com <password for myserviceaccount> -k my.keytab

When I verified the keytab, it showed the key for the SPN was created:

C:\jdk1.6.0_18\jre\bin>ktab.exe -l -k my.keytab
Keytab name: C:\jdk1.6.0_18\jre\bin\my.keytab
KVNO    Principal
------------------------------------------------------------
  1     HTTP/mylaptop.corpnet.mycorp.com@CORPNET.MYCORP.COM

The critical point here is to use the correct password for myserviceaccount to create the keytab file. Since ktab.exe does not verify the correctness of the password. No matter what you put, a keytab file will be created for you. The keytab created with random password even worked for the ‘Jass server’ testing. But it would fail for the client-server applications.

[update May 12, 2010] If you want to use the keytab file created this way with MIT Kerberos, you may check my another post about kvno.

Server section from jaas-krb5.conf

With the newly created keytab, the server section looks like:

server {
	com.sun.security.auth.module.Krb5LoginModule required
	useKeyTab=true
	storeKey=true
	keyTab=my.keytab
	principal="HTTP/mylaptop.corpnet.mycorp.com"
	isInitiator=false;
};

The last line, isInitiator=false is critical to the server section when a keytab is used. Somehow it was not mentioned in the tutorial ( I got it from the reference by Wang).

[update April 15, 2010] You may see my another post talking about isInitiator.

Testing server authenticated against KDC

After copying the keytab file to the same location as Jaas class file, when I ran the testing comand:

java -Djava.security.auth.login.config=jaas-krb5.conf Jaas server

It showed the server was successfully authenticated and ready to process the secure action.

A piece of code change

In class, GssSpNegoClient, the following line was used to define the service principal.

	String serverPrinc = args[0] + "/" + args[1]; 

Actually, it did not work. It should be:

	String serverPrinc = args[0] + "@" + args[1]; 

as defined in GssClient or simply

	String serverPrinc = args[0]; 

as the case in SaslTestClient.

Testing client-server applications

With the above setup, all client-server samples were running successfully, but the JSSE one. Here are the commands to run them:

// Commands for GssServer testing
java -Djava.security.auth.login.config=jaas-krb5.conf GssServer
java -Djava.security.auth.login.config=jaas-krb5.conf GssClient HTTP MYLAPTOP

// Commands for SaslServer testing
java -Djava.security.auth.login.config=jaas-krb5.conf SaslTestServer HTTP MYLAPTOP
java -Djava.security.auth.login.config=jaas-krb5.conf SaslTestClient HTTP MYLAPTOP

// Commands for JsseServer testing
java -Djava.security.auth.login.config=jaas-krb5.conf JsseServer MYLAPTOP
java -Djava.security.auth.login.config=jaas-krb5.conf JsseClient MYLAPTOP

// Commands for GssSpNegoServer testing
java -Djava.security.auth.login.config=jaas-krb5.conf GssSpNegoServer
java -Djava.security.auth.login.config=jaas-krb5.conf GssSpNegoClient HTTP MYLAPTOP

In the tutorial, it mentioned all Kerberos-enabled TLS applications use the same service name, “host”. Since I have used ‘HTTP’ all the way, it is understandable I would run into this problem. The following is the trace stack from the server end:

Exception in thread "main" java.security.PrivilegedActionException: java.io.IOException:
Server principal is HTTP/mylaptop.corpnet.mycorp.com@CORPNET.MYCORP.COM
but ticket is for host/mylaptop.corpnet.mycorp.com@CORPNET.MYCORP.COM
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Unknown Source)
        at Jaas.loginAndAction(Jaas.java:113)
        at JsseServer.main(JsseServer.java:68)
Caused by: java.io.IOException:
Server principal is HTTP/mylaptop.corpnet.mycorp.com@CORPNET.MYCORP.COM
but ticket is for host/mylaptop.corpnet.mycorp.com@CORPNET.MYCORP.COM
        at com.sun.net.ssl.internal.ssl.KerberosClientKeyExchange.(Unknown Source)
        at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at JsseServer$JsseServerAction.run(JsseServer.java:103)
        ... 4 more

The single sign-on feature

The tutorial also mentioned to achieve the SSO feature with Kerberos environment. It is just as simple as adding one line to the client section of the jaas configuration file:

client {
	com.sun.security.auth.module.Krb5LoginModule required
	useTicketCache=true
	principal="mypersonal";
};

However, the once successful client-server applications failed with exceptions from client end:

Exception in thread "main" java.security.PrivilegedActionException: 
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: 
No valid credentials provided (Mechanism level: KDC has no support for encryption type (14))]
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Unknown Source)
        at Jaas.loginAndAction(Jaas.java:113)
        at SaslTestClient.main(SaslTestClient.java:103)
Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: 
No valid credentials provided (Mechanism level: KDC has no support for encryption type (14))]
        at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
        at SaslTestClient$SaslClientAction.run(SaslTestClient.java:145)
        ... 4 more
Caused by: GSSException: No valid credentials provided (Mechanism level: 
KDC has no support for encryption type (14))
        at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source)
        at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
        at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
        ... 6 more
Caused by: KrbException: KDC has no support for encryption type (14)
        at sun.security.krb5.KrbTgsRep.(Unknown Source)
        at sun.security.krb5.KrbTgsReq.getReply(Unknown Source)
        at sun.security.krb5.internal.CredentialsUtil.serviceCreds(Unknown Source)
        at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Unknown Source)
        at sun.security.krb5.Credentials.acquireServiceCreds(Unknown Source)
        ... 9 more
Caused by: KrbException: Identifier doesn't match expected value (906)
        at sun.security.krb5.internal.KDCRep.init(Unknown Source)
        at sun.security.krb5.internal.TGSRep.init(Unknown Source)
        at sun.security.krb5.internal.TGSRep.(Unknown Source)
        ... 14 more

From the exception, it looked like there was something wrong with the encryption type. After further examination, it turned out that it was due to a Windows registry setting that prevented the client from acessing the session key of the TGT.

TGT accessibility

By default, Windows does not allow the session key of a TGT to be accessed. For Windows XP, the registry key and value should be ( see reference by Wang as well):

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos
Value Name: AllowTGTSessionKey
Value Type: REG_DWORD
Value: 0x01

After I set the value in the registry as above, the client applications never asked me password again. SSO accomplished!

Encryption type

Recall the krb5.ini file contains the entries about default_tkt_enctypes and default_tgs_enctypes. Many literatures suggest to use the following:

     default_tkt_enctypes = des3-cbc-sha1 des-cbc-md5 des-cbc-crc
     default_tgs_enctypes = des3-cbc-sha1 des-cbc-md5 des-cbc-crc

Usually that was talking about Window 2000 AD server or J2SE 5.0 configuration. With many new types supported by AD 2003, 2008 and J2SE 6.0. It’s better to check which type is supported by the environment.

Coming with MIT Kerberos for Windows, there is an utility called, Network Identity Manager (netidmgr.exe). It would list all the service you are currently authenticated. Selecting krbtgt/CORPNET.MYCORP.COM and clicking it brought out a window to show the details of the service. From Tab Credential, it listed Service EncType and Session EncType. It revealed ‘RC4-HMAC-NT’ for both. From JGSS Security Enhancement List, it indicated JGSS uses ‘RC4-HMAC’, instead of ‘RC4-HAMC-NT’. That’s how I got my settings in krb5.ini.

Network Identity Manager

References

Ricciardi Kerberos Protocol Tutorial
Wang Kerberos Programming on Windows (original link, broken)
Wang Kerberos Programming on Windows (updated link) [Updated on Dec 29, 2010]
The Jave Monkey Client/Server Hello World in Kerberos, Java and GSS!

The references helped me a lot in understanding Kerberos and JGSS. You sure will find it useful as well.

Advertisements

Tags: , , ,

7 Responses to “Kerberos setup and JAAS configuration for running Sun JGSS tutorial against AD”

  1. Utilize SASL GSSAPI mechanism to achieve Single Sign-on (SSO) for JNDI/LDAP client « Documentum DAA Says:

    […] the procedure to work on SSO solution for Documentum Webtop and Kerberos setup, the word SASL popped up many times during my searching and cought my eyes. From then I had been […]

  2. How to obtain and authenticate Kerberos and SPNEGO tokens with JGSS « Documentum DAA Says:

    […] may refer to Kerberos setup for ways to get kerberso configured properly. The configuration file, bcsLogin.conf used by the […]

  3. The Pirate App Says:

    The Pirate App…

    […]Kerberos setup and JAAS configuration for running Sun JGSS tutorial against AD « Documentum DAA[…]…

  4. SharePoint Webservice from Java Webapp using CXF with Kerberos/NTLM authentication | PHP Developer Resource Says:

    […] you want to use single sign on feature meaning using current user identity take a look here Tagged: cxfJavaKerberosquestionsSharePointweb-services /* * * CONFIGURATION VARIABLES: […]

  5. s Says:

    thanks allen, this post is really a valuable one. appreciate your knowledge share.

  6. Hua Jie Yang Says:

    Hi , can you shall your code on this tutorial?

    When I try to use kerberos authenticate java.net http request to consume window IIS home page, I am always get 401 error.

    Appreciate your help!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: