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:
- Configure and install sec-server-spnego-form-auth
- Test the tomcat app from the Other PC with humanUser1
- Test the tomcat app from WIN-GG8QUO4LVI8 with humanUser1
- Configure and install sec-client-rest-template
1. Configure and install sec-server-spnego-form-auth
Configuration in WIN-GG8QUO4LVI8First 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