A couple of helper classes for and an example of using Constrained Delegation with Kerberos.
The Kerberos Double Hop problem occurs when you have a kerberised service 'A' that needs to talk to another kerberised service 'B' on behalf of a user. Service A can not by default request a new service ticket for service B without constrained delegation (or protocol transition). A good write up can be found here.
Contains helper classes that can be used to perform constrained delegation using spring-security-kerberos and S4U2Proxy.
- springsecuritykerberos package - Contains the changes found in this pull request as well as a tweak to the Sun JAAS config to have
isInitiator=true
. This is necessary to get Krb5ProxyCredential as described in the comment here. - CollaredKerberosTokenFactory - An example/helper for creating SPNEGO tokens using the obtained Krb5ProxyCredential.
- httpclient package - A simple HttpClient SPNEGO scheme that can be used in a KerberosRestTemplate and simply returns the provided token during the SPNEGO sequence.
I set this example up to fulfil my particular use case at the time around the Hadoop stack - that a request from a user would hit a Kerberised service, get passed through a couple of insecure services, and finally hit another kerberised service that required the end users credentials. So collared-kerberos-example-gateway is a kerberised service and collared-kerberos-example-hop isn't, although it makes a kerberised call to a downstream service. It works by generating a service ticket token for the kerberised end service during the gateway interaction, and passing that service ticket as a header to the hop service. The hop service then simply uses that token and KerberosRestTemplate to call the downstream kerberised service. The meat of the constrained delegation is in the gateway example.
The gateway service configured with spring security kerberos that also uses helper classes found in collared-kerberos. Key points to note:
- WebSecurityConfig - Your stock spring security setup with a SPNEGO authentication filter, using the tweaked SunKerberosJaasTicketValidator.
- GatewayController - Obtains the delegated credential after the SPNEGO sequence, puts it in a header and calls the configured hop service.
- HopController - gets the token out of the header and calls the target kerberised service using KerberosRestTemplate, with a custom HttpClient that uses the token at the right point of the SPNEGO sequence.
- Virtualbox
- Patience
- Googling ability - I can't guarantee these instructions will work and will happily accept PRs to fix them, but you'll likely need to work through some problems.
- File -> Preferences -> Network -> Host-only Networks. Make sure there is an adapter.
- Edit it and note down the address.
- Some people get this working using static IPs for the following hosts, but I used a DHCP server and made sure the hosts always got the same IP.
- Download an evaluation Windows Server 2012 R2 from here
- In virtualbox, click new.
- Give your server a good name, leave the defaults, and click create.
- Right click your new server, click on settings, and click on Storage. Click the 'Empty' disk in the 'Storage Tree' section, then click the disc on the far right. Select Choose Virtual Optical Disk File and then find where you downloaded your ISO and select it.
- Click on Network, Adapter 2, Enable Network Adapter. Select Host-Only Adapter in the Attached to drop down and click OK.
- Double click to power it up. Go through the install process making sure to select 'Windows Server 2012 R2 Standard Evaluation (Server with a GUI)'. Do a 'Custom' install and finish up the install.
- After install, give it a password and log in.
- Open up the Server Manager, and click Add Roles and Features. Next, Next, Next. Select Active Directory Domain Services and DNS Server. Next through to the end. You may get a warning about not having a static IP - I couldn't quite figure out how to do this and it worked with DHCP so I left it. Install and then close.
- Click on the orange exclaimation mark and click promote this server to Domain Controller. Select add a new forest and give it a name, e.g. MYCOOLDOMAIN.COM
- Next through the rest of the options and Install. Server will restart.
- Once the server has restarted click start, start typing active and then open Active Directory Users and Groups. Expand your domain and click on Managed Service Accounts. Right click in the white space and click new -> User.
- Give a name for your delegating service like MYCOOLSERVICE and type the same in the User Login Name. Click next and then untick User must change password on next login and tick password never expires and then create.
- Repeat above for another user called DOWNSTREAM - this will be our downstream kerberised service B.
- Repeat above for our end user, e.g. Tom. This will be the user that logs into Windows and uses a browser to call our first kerberised service.
- Create a SPNEGO service principal name (SPN) for MYCOOLSERVICE by opening powershell and running
setspn -s HTTP/mycoolservice.mycooldomain.com MYCOOLSERVICE
. - Create a Keytab for the service by running
ktpass -out C:\Users\Administrator\mycoolservice.keytab -princ HTTP/mycoolservice.mycooldomain.com@MYCOOLDOMAIN.COM -mapUser MYCOOLSERVICE -mapOp set +rndpass -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL
. - Add the MYCOOLSERVICE user principal to the keytab using the command
ktpass -in C:\Users\Administrator\mycoolservice.keytab -out C:\Users\Administrator\mycoolservice.keytab -princ MYCOOLSERVICE@MYCOOLDOMAIN.COM -mapUser MYCOOLSERVICE -mapOp set +rndpass -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL
. Ignore the warning. - Repeat the above for the DOWNSTREAM service, but this time for the SPNEGO principal use HTTP/downstream.mycooldomain.com (although for this example you just need the SPNEGO SPN).
- Configure constrained delegation for the MYCOOLSERVICE user by going back to Active Directory Users and Computers and clicking View -> Advanced Features. Right click on the MYCOOLSERVICE user and click properties. There is now a Delegation tab. Click it and click Trust the user for delegation to specified services only. Click Users or Computers and type downstream and check names and then OK. Select the HTTP downstream.mycooldomain.com service and click OK and OK.
- Get the keytabs of the server for later, e.g. with a share or something.
- Download Ubuntu from here.
- Follow the process as above for creating the virtualbox image.
- Install Ubuntu.
- Get the mycoolservice keytab and place on server.
- Install jdk8 and krb5-workstation.
- Configure krb5.conf.
- Configure NTP and Hosts.
- Clone collared kerberos example projects.
- Configure projects.
- Build and start them.
- Create another Virtualbox Unbutu VM as in the Gateway/Hop one above.
- Get downstream keytab and place on server.
- Install krb5-workstation.
- Configure krb5.conf.
- Configure NTP and Hosts.
- Clone the hadoop-auth example from here.
- Configure as per hadoop auth example instructions to point to downstream principal and keytab.
- Build hadoop auth example
- Download apache Tomcat and extract and start it.
- Put built web app in webapps.
- Get a Windows VM from here
- As per the other virtualbox VMs, create one for Windows.
- Log in as end user.
- Add it to mycooldomain.com.
- Edit IE settings to supply user/password.
- Go to http://mycoolservice.mycooldomain.com:8080/ - If everything works the service should say you're Tom/whatever your end user you set up was.
Because I'm terrible at naming things: Kerberos being a mythological three headed dog, and a collar being a sort of 'constraint' on it. Yeah I know. Terrible.