Authenticating via Kerberos with Keycloak and Windows 2008 Active Directory



The following instructions show you how to configure Keycloak with Windows AD in order to use Kerberos authentication.

Assumptions

  1. The Kerberos realm is VIRTUAL.LOCAL
  2. The hostname used to access Keycloak is virtual.local. This just means we are running Keycloak on the domain controller. In production virtual.local will be replaced with something like keycloak.dev.virtual.local or something like that, giving you a SPN of HTTP/keycloak.dev.virtual.local@VIRTUAL.LOCAL

Configuration

  1. Create a windows domain account called Keycloak.
  2. Run the following command to assign a SPN to the user and generate a keytab file:
    ktpass -out keycloak.keytab -princ HTTP/virtual.local@VIRTUAL.LOCAL -mapUser Keycloak@VIRTUAL.LOCAL -pass password1! -kvno 0 -ptype KRB5_NT_PRINCIPAL -crypto RC4-HMAC-NT
  3. Verify the SPN has been assigned to the user with the command:
    setspn -l Keycloak
  4. Configure the LDAP settings in Keycloak like this. Since we are running Keycloak on the domain controller, we reference LDAP via the local loopback address. Obviously this would change in most production environments.
  5. Configure the Kerberos integration like this:

Configuring Java

You will need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for your version of Java. Download them for Java 8 at http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html, or Java 7 at http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html.

Notes

Don't use port names in the SPN. By default Keycloak will run under port 8080, but this must not be added to the SPN, even though SPNs can contain port details.

To make use of Kerberos authentication from a Windows client, the Keycloak server has to be in a Internet Zone that has User Authentication -> Logon -> Automatic logon with current user name and password enabled. Chrome and IE both respect this settings.


To enable Kerberos authentication in Firefox, you need to add the Keycloak domain to the network.negotiate-auth.trusted-uris setting in about:config.


http://sourceforge.net/p/spnego/discussion/1003768/thread/960ba7ad/ has some useful information that can be used to debug exceptions.

Testing

This page can be used to quickly test the ability for a client to log in.

Get the keycloak.js file from the Keycloak JavaScript Adapter download.

Get the keycloak.json file from Keycloak itself.


<html>
<body>
<script src="keycloak.js"></script>
<script>
var keycloak = new Keycloak('keycloak.json');
keycloak.init({ onLoad: 'login-required' }).success(function(authenticated) {
keycloak.loadUserProfile().success(function(profile) {
alert(JSON.stringify(profile));
});
});
</script>
</body>
</html>

Some notes on Java 8

Builds of Java 8 above 1.8.0_31 have a bug that will throw the Defective token detected (Mechanism level: GSSHeader did not find the right tag) exception. See http://sourceforge.net/p/spnego/discussion/1003769/thread/700b6941/#cb84 for details.

Comments

Anonymous said…
This is the best thing i have seen in a long time Casper
Vincent Yin said…
Your ktpass command specifies the -mapUser argument as "Keycloak@VIRTUAL.LOCAL". The upper-case VIRTUAL.LOCAL suggests that it refers to the Kerberos Realm name.

I don't think that's correct. That parameter specifies an AD domain username which should be in one of two formats: either "keycloak@virtual.local" or "VIRTUAL\keycloak".

The fact that your original command worked is because your AD domain name happens to be the lowercase "virtual.local" and Windows username is case-insensitive: KEYCLOAK@VIRTUAL.LOCAL, keycloak@virtual.local, virtual\keycloak and VIRTUAL\KEYCLOAK are all valid usernames for the same AD account.

So, for clarity of concept, it would be better to change -mapUser to the all-lowercase keycloak@virtual.local.
pooja said…
I'm using java 8 uodate 25 but still getting that GSSException: defective token detected error. why this issue is coming
lena said…
This comment has been removed by the author.

Popular posts from this blog

MinHash for dummies

Fixing OpenVPN "Authenticate/Decrypt packet error: cipher final failed"