Buscar este blog

sábado, 27 de agosto de 2016

Windows Server - Spring Security Kerberos authentication example

This post is a step by step guide to configure a Kerberos service which is accesible for human users (by using a web browser) and for other java applications (by using a HTTP client).
This post is almost entirely based in the Spring Security Kerberos reference documentation. I just have taken the parts I needed to develop a funcionality in one of my applications.

The overview of the solution is as follows:
  • There is a Windows Server 2008 R2 machine called WIN-GG8QUO4LVI8.test.com.
  • In this server the Active Directory and KDC (Key Distribution Center) are running.
  • The AD has three users: tomcat, user1 and humanUser1.
  • The root domain (and forest, as there is just one domain) is TEST.COM.
  • There is a second machine outside the domain. A Windows 7 machine.
  • In this PC, the sec-server-spnego-form-auth application is deployed.
  • This service will be called neo.example.org.
  • In this PC, the rest client sc-client-rest-template will also be "deployed".


The objectives are:
  • When humanUser is logged in WIN-GG8QUO4LVI8.test.com, he can access the tomcat app without introducing his username neither password. His identity is loaded from the windows session.
  • When humanUser is logged in the other PC, he can access the tomcat app by introducing his username and password.
  • The rest client can access the tomcat app by identifying itself with a username (user1) and his keytab file.


This image summarize this infrastructure:


So, I have my Active Directory configured with de domain "test.com" in a computer named "WIN-GG8QUO4LVI8", ie, my Domain Controller.


Based on this information, I can create a kerberos conf file (or .ini). The content of krb5.conf file is:
[libdefaults]
 default_realm = TEST.COM
 default_tkt_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
 default_tgs_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
 permitted_enctypes   = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc

[realms]
 TEST.COM  = {
  kdc = WIN-GG8QUO4LVI8.test.com
  default_domain = TEST.COM
 }

[domain_realm]
 .TEST.COM = TEST.COM

In the Active Directory I have the three necessary users. For example:



The steps  I'll follow to complete the deployments are as follow:
  1. Configure and install sec-server-spnego-form-auth
  2. Test the tomcat app from the Other PC with humanUser1
  3. Test the tomcat app from WIN-GG8QUO4LVI8 with humanUser1
  4. Configure and install sec-client-rest-template

1. Configure and install sec-server-spnego-form-auth

Configuration in WIN-GG8QUO4LVI8
First we need to setup a Service Principal Name (SPN) for the sec-server-spnego-form-auth.
A service is any process that do something, in this case, the tomcat app. Services are identified uniquely in the form of "<service class>/<host>:<port>[/<service name>]", and are they asociated with a login account name.

Our SPN will be "HTTP/neo.example.org" and the user associated will be "tomcat".
> setspn -A HTTP/neo.example.org tomcat

> setspn -L tomcat
Registered ServicePrincipalNames for CN=tomcat tomcat.,CN=Users,DC=test,DC=com:
        HTTP/neo.example.org

Now we need to generate a keytab file for this service and map the SPN created previously. Basically, we are saying that this keytab file belongs to this SPN, which is also asociated with a user.
You need to use the ktpass command:
> ktpass -out ./tomcat.keytab -mapuser tomcat@TEST.COM -princ HTTP/neo.example.org@TEST.COM -pass Password# -ptype KRB5_NT_PRINCIPAL -crypto ALL


> "c:\Program Files (x86)\Java\jre1.8.0_101\bin\klist.exe" -k -t -k tomcat.keytab

Key tab: tomcat.keytab, 5 entries found.

[1] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[2] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[3] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[4] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00
[5] Service principal: HTTP/neo.example.org@TEST.COM
         KVNO: 3
         Time stamp: Jan 01, 1970 01:00:00

The java klist command allows to list the entries in the keytab file. A keytab file contains pairs of kerberos principals an encrypted keys. In this case, the principal is the service.

Configuration in the Other PC
Once we have all the kerberos configuration done, we can start to prepare our tomcat application sec-server-spnego-form-auth.
This spring boot application has a configuration file, application.yml, with two importan keys:
  • service-principal. The name of the service that this application is providing.
  • keytab-localtion. The path to the keytab file which contains the keys wich authenticate this application in the KDC.

With de information above, the application.yml file would be:
server:
    port: 8080
app:
    service-principal: HTTP/neo.example.org@TEST.COM
    keytab-location: D:/kerberos/tomcat.keytab

Remember that we also have the krb5.conf with de global configuration. We can tell our app to use it with the argument -Djava.security.krb5.conf=/path/to/krb5.conf.

In order to start this application you have to execute the following command:
java -Djava.security.krb5.conf=D:/kerberos/krb5.conf -jar sec-server-spnego-form-auth-1.0.2.BUILD-SNAPSHOT.jar

Ok. Our tomcat app is up and running.

2. Test the tomcat app from the Other PC with humanUser1

In the Other PC, I had the following IPs in my hosts file:
127.0.0.1   neo.example.org

192.168.65.129 WIN-GG8QUO4LVI8
192.168.65.129 WIN-GG8QUO4LVI8.test.com

When a user tries to access to http://neo.example.org:8080/hello, he will get the auth form. This is because this user is outside the domain.


3. Test the tomcat app from WIN-GG8QUO4LVI8 with humanUser1

Now, humanUser1 logs in WIN-GG8QUO4LVI8, which is a PC inside the domain (well, it is the server domain...).
When this user tries to access to http://neo.example.org:8080/hello, he will enter automatically.

I will use firefox, so you need to configure the following:
  • Open Firefox.
  • At address field, type about:config.
  • In filter/search, type negotiate.
  • Set parameter network.negotiate-auth.trusted-uris to http://neo.example.org:8080 (if you already have other URL, you need to separate them by using ",").

I also added this URL to my local intranet sites in the Internet Explorer configuration.

4. Configure and install sec-client-rest-template

Fine. The human users have access to the web application. If the user is loged in inside the domain, he doesn´t need to autenticate again (Single Sign On), but if the user try to access from outside, he needs to use his login and password.

Now I want to authenticate a java application which will make a http connection (a GET request) to the secure page in the sec-server-spnego-form-auth application.

Configuration in WIN-GG8QUO4LVI8
You need to create a second keytab file. In this case, this file will contain the keys for user1, which will be the user used by the sec-client-rest-template.
Previously we created a keytabfile for the tomcat user, which is the acconut name asociated with the service, by using the ktpass command. Now we just need to create the ketabfile for a external user, without to associate this user with any service.

We use the ktab tool, shipped with Java.
> "c:\Program Files (x86)\Java\jre1.8.0_101\bin\ktab.exe" -a user1 Password# -k user1.keytab

> "c:\Program Files (x86)\Java\jre1.8.0_101\bin\klist.exe" -k -t -K user1.keytab

Key tab: user1.keytab, 3 entries found.

[1] Service principal: user1@TEST.COM
         KVNO: 1
         Key: 0x97bb5f77eb114814e2c1e639ec914429
         Time stamp: Aug 26,  2016 16:09:43
[2] Service principal: user1@TEST.COM
         KVNO: 1
         Key: 0x4f5ea81531e5136807d9fe9d75d0f2e6cbd9b6eacd546d7f
         Time stamp: Aug 26,  2016 16:09:43
[3] Service principal: user1@TEST.COM
         KVNO: 1
         Key: 0x63245e61ad75fbc0b9360b4e380d83d8
         Time stamp: Aug 26,  2016 16:09:43

Configuration in the Other PC
Once we have keytab file we can start to prepare our tomcat application sec-client-rest-template.
This spring boot application has a configuration file, application.yml, with two important keys:
  • user-principal. The user that this application will use to authenticate itself.
  • keytab-localtion. The path to the keytab file wich contains the keys wich authenticate this application in the KDC.
  • access-url: The URL of our service.

With the information above, the application.yml file would be:
app:
    user-principal: user1@TEST.COM
    keytab-location: D:/kerberos/user1.keytab
    access-url: http://neo.example.org:8080/hello


Remember that we also have the krb5.conf with de global configuration. We can tell our app to use it with de argument -Djava.security.krb5.conf=/path/to/krb5.conf.

In order to start this application you have to execute the following command:
java -Djava.security.krb5.conf=D:/kerberos/krb5.conf -jar sec-client-rest-template-1.0.2.BUILD-SNAPSHOT.jar

No hay comentarios:

Publicar un comentario