Skip to content
Hamish Moffatt edited this page Mar 22, 2019 · 13 revisions

Using mod_auth_openidc with Keycloak

Keycloak and mod_auth_openidc is a great fit for self hosted authentication with user administration. Official docs contains a guide.

One can use mod_auth_openidc as an OpenID Connect Relying Party with Keycloak, which is described hereafter, or one can use it as an OAuth 2.0 Resource Server, whose setup is described at https://github.com/pingidentity/mod_auth_openidc/wiki/OAuth-2.0-Resource-Server#keycloak.

There's a sample setup for local OpenID Connect testing using Docker at https://github.com/Reposoft/openidc-keycloak-test.

You create an openid-connect type "client" in your Keycloak realm. Set access type to "Confidential", get a secret, put that secret in a conf with something like:

	OIDCProviderMetadataURL https://keycloak.example.net/auth/realms/Testrealm/.well-known/openid-configuration
	OIDCRedirectURI https://myserver.example.not/oauth2callback
	OIDCCryptoPassphrase 0123456789
	OIDCClientID testclient
	OIDCClientSecret ca446a2d-a65f-4e84-95a7-d20eb36989d8
	# See https://github.com/Reposoft/openidc-keycloak-test/issues/7
	OIDCProviderTokenEndpointAuth client_secret_basic

	OIDCRemoteUserClaim email
	OIDCScope "openid email"

Without an OICDRemoteUserClaim you'd get usernames like [user-uuid]@[keycloak-realm-url] which is unuseful. E-mail works well with Keycloak: [email protected] can authenticate as both user and the full address.

Single Sign On (SSO) works. Just duplicate your config in multiple VirtualHosts or httpd instances and modify the OIDCRedirectURI accordingly. You can add multiple "Valid Redirect URIs" in the Keycloak admin ui.

Roles

To leverage realm_access or other roles defined in Keycloak, make sure that Keycloak returns those claims from the user info endpoint rather than associating them with the access token (or even putting them in the ID token). To make sure that role information is accurate and up-to-date you can use OIDCUserInfoRefreshInterval.

To add these claims to the user info endpoint, edit the mappings in the Client Scopes settings of the realm, or in the mappers settings of individual clients in the realm. An example mapping for the realm access roles is:

  • name: roles
  • mapper type: user realm role
  • multivalued: on
  • token claim name: roles (note that multipart names like "realm_access.roles" don't seem to work)
  • claim JSON type: string
  • add to userinfo: enabled

This results in userinfo returning:

{
  "email": "[email protected]",
  "email_verified": false,
  "family_name": "Blogs",
  "given_name": "Joe",
  "name": "Joe Blogs",
  "preferred_username": "joe",
  "roles": [
    "realm_role_1",
    "realm_role_2",
    "offline_access",
    "uma_authorization"
  ],
  "sub": "e87ee895-e345-431e-8c94-2197655fc9d5"
}