Kerberos

Keycloak supports login with a Kerberos ticket through the Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) protocol. SPNEGO authenticates transparently through the web browser after the user authenticates the session. For non-web cases, or when a ticket is not available during login, Keycloak supports login with Kerberos username and password.

A typical use case for web authentication is the following:

  1. The user logs into the desktop.

  2. The user accesses a web application secured by Keycloak using a browser.

  3. The application redirects to Keycloak login.

  4. Keycloak renders the HTML login screen with status 401 and HTTP header WWW-Authenticate: Negotiate

  5. If the browser has a Kerberos ticket from desktop login, the browser transfers the desktop sign-on information to Keycloak in header Authorization: Negotiate 'spnego-token'. Otherwise, it displays the standard login screen, and the user enters the login credentials.

  6. Keycloak validates the token from the browser and authenticates the user.

  7. If using LDAPFederationProvider with Kerberos authentication support, Keycloak provisions user data from LDAP. If using KerberosFederationProvider, Keycloak lets the user update the profile and pre-fill login data.

  8. Keycloak returns to the application. Keycloak and the application communicate through OpenID Connect or SAML messages. Keycloak acts as a broker to Kerberos/SPNEGO login. Therefore Keycloak authenticating through Kerberos is hidden from the application.

Perform the following steps to set up Kerberos authentication:

  1. The setup and configuration of the Kerberos server (KDC).

  2. The setup and configuration of the Keycloak server.

  3. The setup and configuration of the client machines.

Setup of Kerberos server

The steps to set up a Kerberos server depends on the operating system (OS) and the Kerberos vendor. Consult Windows Active Directory, MIT Kerberos, and your OS documentation for instructions on setting up and configuring a Kerberos server.

During setup, perform these steps:

  1. Add some user principals to your Kerberos database. You can also integrate your Kerberos with LDAP, so user accounts provision from the LDAP server.

  2. Add service principal for "HTTP" service. For example, if the Keycloak server runs on www.mydomain.org, add the service principal HTTP/www.mydomain.org@<kerberos realm>.

    On MIT Kerberos, you run a "kadmin" session. On a machine with MIT Kerberos, you can use the command:

sudo kadmin.local

Then, add HTTP principal and export its key to a keytab file with commands such as:

addprinc -randkey HTTP/www.mydomain.org@MYDOMAIN.ORG
ktadd -k /tmp/http.keytab HTTP/www.mydomain.org@MYDOMAIN.ORG

Ensure the keytab file /tmp/http.keytab is accessible on the host where Keycloak is running.

Setup and configuration of Keycloak server

Install a Kerberos client on your machine.

Procedure
  1. Install a Kerberos client. If your machine runs Fedora, Ubuntu, or RHEL, install the freeipa-client package, containing a Kerberos client and other utilities.

  2. Configure the Kerberos client (on Linux, the configuration settings are in the /etc/krb5.conf file ).

    Add your Kerberos realm to the configuration and configure the HTTP domains your server runs on.

    For example, for the MYDOMAIN.ORG realm, you can configure the domain_realm section like this:

    [domain_realm]
      .mydomain.org = MYDOMAIN.ORG
      mydomain.org = MYDOMAIN.ORG
  3. Export the keytab file with the HTTP principal and ensure the file is accessible to the process running the Keycloak server. For production, ensure that the file is readable by this process only.

    For the MIT Kerberos example above, we exported keytab to the /tmp/http.keytab file. If your Key Distribution Centre (KDC) and Keycloak run on the same host, the file is already available.

Enabling SPNEGO processing

By default, Keycloak disables SPNEGO protocol support. To enable it, go to the browser flow and enable Kerberos.

Browser flow

Browser Flow

Set the Kerberos requirement from disabled to alternative (Kerberos is optional) or required (browser must have Kerberos enabled). If you have not configured the browser to work with SPNEGO or Kerberos, Keycloak falls back to the regular login screen.

Configure Kerberos user storage federation providerxs

You must now use User Storage Federation to configure how Keycloak interprets Kerberos tickets. Two different federation providers exist with Kerberos authentication support.

To authenticate with Kerberos backed by an LDAP server, configure the LDAP Federation Provider.

Procedure
  1. Go to the configuration page for your LDAP provider.

    Ldap kerberos integration

    LDAP Kerberos Integration

  2. Toggle Allow Kerberos authentication to ON

Allow Kerberos authentication makes Keycloak use the Kerberos principal access user information so information can import into the Keycloak environment.

If an LDAP server is not backing up your Kerberos solution, use the Kerberos User Storage Federation Provider.

Procedure
  1. Click User Federation in the menu.

  2. Select Kerberos from the Add provider select box.

    Kerberos user storage provider

    Kerberos User Storage Provider

The Kerberos provider parses the Kerberos ticket for simple principal information and imports the information into the local Keycloak database. User profile information, such as first name, last name, and email, are not provisioned.

Setup and configuration of client machines

Client machines must have a Kerberos client and set up the krb5.conf as described above. The client machines must also enable SPNEGO login support in their browser. See configuring Firefox for Kerberos if you are using the Firefox browser.

The .mydomain.org URI must be in the network.negotiate-auth.trusted-uris configuration option.

In Windows domains, clients do not need to adjust their configuration. Internet Explorer and Edge can already participate in SPNEGO authentication.

Example setups

Keycloak and FreeIPA docker image

When you install docker, run a docker image with the FreeIPA server installed. FreeIPA provides an integrated security solution with MIT Kerberos and 389 LDAP server. The image also contains a Keycloak server configured with an LDAP Federation provider and enabled SPNEGO/Kerberos authentication against the FreeIPA server. See details here.

ApacheDS testing Kerberos server

For quick testing and unit tests, use a simple ApacheDS Kerberos server. You must build Keycloak from the source and then run the Kerberos server with the maven-exec-plugin from our test suite. See details here.

Credential delegation

Kerberos supports the credential delegation. Applications may need access to the Kerberos ticket so they can re-use it to interact with other services secured by Kerberos. Because the Keycloak server processed the SPNEGO protocol, you must propagate the GSS credential to your application within the OpenID Connect token claim or a SAML assertion attribute. Keycloak transmits this to your application from the Keycloak server. To insert this claim into the token or assertion, each application must enable the built-in protocol mapper gss delegation credential. This mapper is available in the Mappers tab of the application’s client page. See Protocol Mappers chapter for more details.

Applications must deserialize the claim it receives from Keycloak before using it to make GSS calls against other services. When you deserialize the credential from the access token to the GSSCredential object, create the GSSContext with this credential passed to the GSSManager.createContext method. For example:

// Obtain accessToken in your application.
KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) servletReq.getUserPrincipal();
AccessToken accessToken = keycloakPrincipal.getKeycloakSecurityContext().getToken();

// Retrieve Kerberos credential from accessToken and deserialize it
String serializedGssCredential = (String) accessToken.getOtherClaims().
    get(org.keycloak.common.constants.KerberosConstants.GSS_DELEGATION_CREDENTIAL);

GSSCredential deserializedGssCredential = org.keycloak.common.util.KerberosSerializationUtils.
    deserializeCredential(serializedGssCredential);

// Create GSSContext to call other Kerberos-secured services
GSSContext context = gssManager.createContext(serviceName, krb5Oid,
    deserializedGssCredential, GSSContext.DEFAULT_LIFETIME);

Examples of this code exist in examples/kerberos in the Keycloak example distribution or demo distribution download. You can also check the example sources directly here.

Configure forwardable Kerberos tickets in krb5.conf file and add support for delegated credentials to your browser.

Credential delegation has security implications, so use it only if necessary and only with HTTPS. See this article for more details and an example.

Cross-realm trust

In the Kerberos protocol, the realm is a set of Kerberos principals. The definition of these principals exists in the Kerberos database, which is typically an LDAP server.

The Kerberos protocol allows cross-realm trust. For example, if 2 Kerberos realms, A and B, exist, then cross-realm trust will allow the users from realm A to access realm B’s resources. Realm B trusts realm A.

Kerberos cross-realm trust

kerberos trust basic

The Keycloak server supports cross-realm trust. To implement this, perform the following:

  • Configure the Kerberos servers for the cross-realm trust. Implementing this step depends on the Kerberos server implementations. This step is necessary to add the Kerberos principal krbtgt/B@A to the Kerberos databases of realm A and B. This principal must have the same keys on both Kerberos realms. The principals must have the same password, key version numbers, and ciphers in both realms. Consult the Kerberos server documentation for more details.

The cross-realm trust is unidirectional by default. You must add the principal krbtgt/A@B to both Kerberos databases for bidirectional trust between realm A and realm B. However, trust is transitive by default. If realm B trusts realm A and realm C trusts realm B, then realm C trusts realm A without the principal, krbtgt/C@A, available. Additional configuration (for example, capaths) may be necessary on the Kerberos client-side so clients can find the trust path. Consult the Kerberos documentation for more details.

  • Configure Keycloak server

    • When using an LDAP storage provider with Kerberos support, configure the server principal for realm B, as in this example: HTTP/mydomain.com@B. The LDAP server must find the users from realm A if users from realm A are to successfully authenticate to Keycloak, because Keycloak must perform the SPNEGO flow and then find the users.

For example, Kerberos principal user john@A must be available in the LDAP under an LDAP DN such as uid=john,ou=People,dc=example,dc=com. If you want users from realm A and B to authenticate, ensure that LDAP can find users from both realms A and B.

  • When using a Kerberos user storage provider (typically, Kerberos without LDAP integration), configure the server principal as HTTP/mydomain.com@B, and users from Kerberos realms A and B must be able to authenticate.

When using the Kerberos user storage provider, there cannot be conflicting users among Kerberos realms. If conflicting users exist, Keycloak maps them to the same user.

Troubleshooting

If you have issues, enable additional logging to debug the problem:

  • Enable Debug flag in the Admin Console for Kerberos or LDAP federation providers

  • Enable TRACE logging for category org.keycloak to receive more information in server logs

  • Add system properties -Dsun.security.krb5.debug=true and -Dsun.security.spnego.debug=true