Monday, 20 April 2015

Kerberos support in Keycloak

From the version 1.2.0.Beta1, Keycloak supports login with Kerberos ticket through SPNEGO. SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) is used to authenticate transparently through the web browser after the user has been authenticated with Kerberos when logging-in his desktop session. For non-web cases or when Kerberos ticket is not available during login, Keycloak also supports login with Kerberos username/password.


A typical use case for web authentication is the following:

  • User logs into his desktop (Such as a Windows machine in Active Directory domain or Linux machine with Kerberos integration enabled).
  • User then uses his browser (IE/Firefox/Chrome) to access a web application secured by Keycloak.
  • Application redirects to Keycloak login.
  • Keycloak sends HTML login screen together with status 401 and HTTP header WWW-Authenticate: Negotiate
  • In case that browser has Kerberos ticket from desktop login, it transfers the desktop sign on information to the Keycloak in header Authorization: Negotiate 'spnego-kerberos-token' . Otherwise it just displays login screen.
  • Keycloak validates token from browser and authenticates user. It provisions user data from LDAP (in case of LDAPFederationProvider with Kerberos authentication support) or let user to update his profile and prefill data (in case of KerberosFederationProvider).
  • Keycloak returns back to the application. Communication between Keycloak and application happens through OpenID Connect or SAML messages. The fact that Keycloak was authenticated through Kerberos is hidden from the application. So Keycloak acts as broker to Kerberos/SPNEGO login.

Keycloak also supports credential delegation. In this case, the web application might be able to reuse the Kerberos ticket and forwards it to another service secured by Kerberos (for example LDAP server or IMAP server). The tricky part is, that SPNEGO authentication happens on Keycloak server side, but you want to use the ticket on the application side. For this scenario, we serialize the GSS Credential with the underlying ticket and send it to the application in the OpenID Connect access token. For this scenario there are 2 more points:

  • Application deserializes the GSS credential with Kerberos ticket sent to it in access token from Keycloak
  • Application uses Kerberos ticket for sending request to another service secured by Kerberos

The whole flow may look complicated, but from the user perspective, it's the opposite! User with Kerberos ticket just visits the URL of the web application and he is logged automatically without even seeing Keycloak login screen.


For the Kerberos setup, you need to install and configure the Kerberos server and Kerberos client. You also need to setup your web browser. Also you need to export keytab file from your kerberos server and make it available to Keycloak. But these steps are not specific for Keycloak (you always need to do them for SPNEGO login support in any kind of web applications) and they are specific according to your OS and Kerberos vendor, so they are not described in details here.

Keycloak specific steps are just:

  • Setup of federation provider in keycloak admin console. You can either setup:
    • Kerberos federation provider - This provider is useful if you want to authenticate with Kerberos NOT backed by LDAP server.
    • LDAP federation provider - This provider is useful if you want to authenticate with Kerberos backed by LDAP server. Kerberos backed by LDAP server is very often the case in production for environments like FreeIPA or MSAD Windows domain
  • Enable GSS credential protocol mapper for your application (This is mandatory only if you need credential delegation).

For more details, take a look at Keycloak documentation, which describes everything in details and also points you to the Kerberos credential delegation example and FreeIPA Keycloak docker image .


  1. good article. was useful for me!

  2. Hi Marek,

    thanks for this article! I've got one advanced question.
    I'm working on a flow, where

    first: kerberos authentication is tried, and
    second: a custom login authenticator is called. I removed the normal login page and set up my own login-form based on AbstractUsernameFormAuthenticator.

    Everything is fine so far, except of the redirect url. As you state, the Browser (testing with ff57) is giving a 401 and shows the login page. So far, so good. But:

    The URL I get to when calling the loginpage looks like this:


    Now I have to integrate this page to a client-app, with links to e.g. "home". Problem is, simply said: no redirect_uri queryparam anymore at my custom login page.

    Now it is not possible for me to get my freemarker template to use the correct environment base-url. I know I can set this via admin itnerfaces' baseurl param, but when you have multiple stages with own dns entries (...-dev, ...-qa)this gets unhandy.

    My only solution so-far is to get document.referer via JS in my custom template.ftl and extract my base-url, but this is somewhat quirky. Perhaps you could give me another solution? I thought about getting the httprequest in backend, getting the baseurl of the referer, and then setting a custom param redirect-url for freemarker template, but after I looked at I can't see how to get the current request and its corresponding headers from my template.

    Then I found your answer here:
    which seemed to be quite good, but after trying to get the variable via
    context.form().setAttribute("referer", context.getHttpRequest().getAttribute("referer")); in the authenticate-method of my custom authenticator,
    and trying to get it in login.ftl (and template.ftl) via ${referer} I got the normal freemarker error when a variable isn't defined. Perhaps you could help me out here! would be great.


Please only add comments directly associated with the post. For general questions use the Keycloak user mailing list.