Keycloak as an Identity Provider

Keycloakfootnote:[Keycloak is a trademark of The Linux Foundation.] is an "open-source identity and access management" solution that can be used as an identity provider (IdP) for user authentication and authorization.

The following describes how to configure BPC with Keycloak as the Identity Provider.

Prerequisites

You have installed Keycloak and have administrative access to both Keycloak and BPC.

You should always use the latest version of Keycloak whenever possible to avoid security risks.

Keycloak Configuration

Please create a realm for the BPC or use an existing realm that you may already be using for other applications.

We do not recommend using the realm master. This realm should be used exclusively for administrative Keycloak access.

A script that configures the following items via the API can be found in the section Script for Automatic Setup.

Create a client

To enable the BPC to communicate with Keycloak, a client must be created.

  1. Make sure you have selected the correct realm.

  2. Select "Clients" on the left-hand side

  3. Create a new client using "Create client"

  4. Select "OpenID Connect" as the "Client type"

  5. Assign a client ID, such as bpc.
    This must later match the configuration client_id in BPC.

  6. Enable "Client authentication". In older Keycloak versions, this corresponds to the "confidential" access type.

  7. Under "Valid redirect URIs," enter the URL of your BPC. For example, “https://BPC.example.com/”

  8. Save the client

  9. In the “Passwords” (or “Credentials”) tab, you can view (and also change) the client secret.
    This must later match the configuration client_secret in the BPC.

Create BPC Roles

To appoint BPC administrators, you need the role bpcadmin.

  1. Select “Realm Roles” on the left side

  2. Use “Create role” to create the role bpcadmin.

Create or Assign a BPC Administrator

For a user to be a BPC Administrator, they need the role bpcadmin.

  1. Select "Users" on the left-hand side

  2. Use "Add User" to or select an existing user

  3. Assign the role bpcadmin to the user

Configure Role Mappings

In order for BPC to successfully recognize the roles and for Identity Management API to be usable (required for user management in the frontend), the “Add to access token” option must be enabled for the Role-Client-Scopes.

This should be set automatically when creating a new realm.

If it is not set, navigate to Client Scopes > Roles > Mappers on the Keycloak administration page in the BPC realm and enable the option for both mappers, “realm roles” and “client roles.”

role mapping

BPC Configuration

In BPC, Keycloak must be added as an Identity Provider under Backend Connections and then specified as the Identity Provider to be used in the Core Services settings.

When BPC starts, backend Connections are automatically created that can be used for Keycloak. These contain a suitable placeholder configuration and are named Keycloak and OIDC. See also Identity Provider Keycloak vs. OIDC

Identity Provider Keycloak vs. OIDC

You have the option to connect Keycloak in two different ways (IdentityProvider OpenID Connect (OIDC) or Keycloak). In both variants, the actual authentication takes place via the OpenID Connect protocol. In the pure OpenID Connect (OIDC) variant, user administration takes place exclusively in Keycloak. If you select "Keycloak," the User Management / Identity Manager integrated into BPC can be used.

Up to and including BPC 4.2.4, when using the type Keycloak, a Keycloak admin user must also be specified. See the BPC 4.1 documentation for details. This also applies up to and including version 4.2.4.

Specific Configuration of the Backend Connection (BPC Version < 4.2.13)

The following settings specific to this Identity Provider can be found in the Backend Connections of type identity_provider. For the general configuration of the Backend Connections of type identity_provider, see General Identity Provider Configuration.

Setting (Key) Group Example value Description

IdentityProvider
(identityProvider)

config

Keycloak or OpenID Connect (OIDC)

Set Keycloak or OIDC as the IdP for the backend connection.
See also Identity Provider Keycloak vs. OIDC

IdentityProvider_URL
(identityProvider.url)

config

`https://localhost:8080/auth/realms/bpc/.well-known/openid-configuration`

OIDC Discovery Endpoint

IdentityProvider_Configuration
(identityProvider_configuration)

config

{
    "post_authentication_redirect_uri": "http://localhost:8181/",
    "claim_name_roles": "resource_access.bpc.roles,realm_access.roles",
    "scope": "openid profile email address phone roles",
    "client_secret": "bpc-test-only",
    "post_logout_redirect_uri": "http://localhost:8181",
    "client_id": "bpc"
}

The configuration for Keycloak access. The URLs here must be adjusted according to the BPC and Keycloak.
See OIDC / Keycloak connection parameters

OIDC / Keycloak connection parameters

The following parameters can be configured in the JSON setting identityProvider_configuration:

Additional configurations are required for BPC installations up to and including version 4.2.4. See the BPC 4.1 documentation for details. This also applies here up to and including version 4.2.4.

Attribute Example value Description

post_authentication_redirect_uri

The user is redirected to this address after logging in.
This URL must be allowed in the Keycloak client and should point to the BPC.

claim_name_roles

realm_access.roles

A comma-separated list of all claim names from which the user’s roles are extracted.

claim_name_organisations

organisations

A comma-separated list of all claim names from which the user’s organizations are extracted.

claim_name_rights

rights

Comma-separated list of all claim names from which the user’s rights are extracted.

scope

openid profile email address phone roles

OIDC scopes that are requested during authentication with the OIDC provider. If scopes are requested that do not exist or for which the client is not authorized, authentication errors may occur.

client_id

bpc

ID of the client configured in the OIDC provider through which access is to be granted.

client_secret

bpc-test-only

Secret used to authenticate client access.

Specific Configuration of the Backend Connection (BPC Version >= 4.2.13)

The following settings specific to this Identity Provider can be found at Backend Connections of type identity_provider. For general configuration of the Backend Connections of type identity_provider, see General Identity Provider Configuration.

Setting (Key) Group Example Value Description

IdentityProvider
(identityProvider)

config

Keycloak or OpenID Connect (OIDC)

Set Keycloak or OIDC as the IdP for the backend connection.
See also Identity Provider Keycloak vs. OIDC

IdentityProvider_OIDC_MetadataDiscoveryURI
(identityProvider_oidc_metadataDiscoveryUri)

oidc

[
    {
       "pattern": ".*",
       "uri": "https://localhost:8080/auth/realms/bpc/.well-known/openid-configuration"
    }
]

OIDC Discovery Endpoint.
See also Keycloak and Dynamic Redirect URIs.

IdentityProvider_OIDC_PostAuthenticationRedirectURI
(identityProvider_oidc_postAuthenticationRedirectUri)

oidc

[
    {
       "pattern": ".*",
       "uri": "http://localhost:8181/"
    }
]

The user is redirected to this address after logging in.
This URL must be allowed in the Keycloak client and should point to the BPC.
See also Keycloak and Dynamic Redirect URIs.

IdentityProvider_OIDC_PostLogoutRedirectURI
(identityProvider_oidc_postLogoutRedirectUri)

oidc

[
    {
       "pattern": ".*",
       "uri": "http://localhost:8181"
    }
]

The user is redirected to this address after logging out.
This URL must be allowed in the Keycloak client.
See also Keycloak and Dynamic Redirect URIs.

IdentityProvider_OIDC_ClaimNameRoles
(identityProvider_oidc_claimNameRoles)

oidc

realm_access.roles

Comma-separated list of all claim names from which the user’s roles are extracted.

IdentityProvider_OIDC_ClaimNameOrganisations
(identityProvider_oidc_claimNameOrganisations)

oidc

organisations

Comma-separated list of all claim names from which the user’s organizations are extracted.

IdentityProvider_OIDC_ClaimNameRights
(identityProvider_oidc_claimNameRights)

oidc

rights

Comma-separated list of all claim names from which the user’s rights are extracted.

IdentityProvider_OIDC_Scope
(identityProvider_oidc_scope)

oidc

openid profile email address phone roles

OIDC scopes that are requested during authentication with the OIDC provider. If scopes are requested that do not exist or for which the client is not authorized, authentication errors may occur.

IdentityProvider_OIDC_ClientId
(identityProvider_oidc_clientId)

oidc

bpc

ID of the client configured in the OIDC provider through which access is to be granted.

IdentityProvider_OIDC_ClientSecret
(identityProvider_oidc_clientSecret)

oidc

bpc-test-only

Secret for authenticating client access.

PKCE method
(identityProvider_oidc_pkceMethod)

oidc

S256

The PKCE (Proof Key for Code Exchange) method used for a hardened login flow. You can choose between S256 (recommended), plain, or none (no PKCE). The selected PKCE method must be supported by Keycloak and, if necessary, configured in the corresponding client.

BPC Integration

If you selected the type “ Keycloak ” for the identityProvider ” setting, various integrations are available to you.

The BPC provides access to various user management functions through its integrated user management.

Users can also perform various actions on Keycloak via the User Account Menu plugin.

Script for Automatic Setup

The following script can be used for development and test environments. This script calls the Keycloak Admin REST API and sets up a new realm bpc. This realm is then configured to work with the preconfigured identity provider Keycloak (ID: idp_keycloak).

The configuration of the backend Connection initially provided by BPC Keycloak (ID: idp_keycloak) was adjusted in BPC 4.2.5 to match this example. If your BPC was initially installed with a version earlier than 4.2.5, you can delete this Identity Provider from the Backend Connections. After a restart, it will be restored with the new default settings. Alternatively, you can customize the script (e.g., the client IDs).

The script can be used, for example, when temporarily starting Keycloak via Docker for testing purposes.

docker run --rm -p 8443:8443 -p 8080:8080 \
    -e KEYCLOAK_ADMIN=admin \
    -e KEYCLOAK_ADMIN_PASSWORD=admin \
    -e KC_FEATURES=token-exchange \
    quay.io/keycloak/keycloak start-dev --hostname=localhost

The script’s variables should be adjusted as needed. However, it is not necessary to set ADMIN_USER and ADMIN_PASSWORD. These two variables are prompted for when starting via the terminal.

  1. createBpcRealm.sh

#!/bin/bash

# Keycloak Server URL und Admin Credentials
KEYCLOAK_URL="http://localhost:8080"
KEYCLOAK_REALM="master"
ADMIN_USER=""
ADMIN_PASSWORD=""

# Neue Realm-, Client- und Benutzer-Konfiguration
NEW_REALM="bpc"
NEW_CLIENT="bpc"
CLIENT_SECRET="bpc-test-only"
NEW_ROLE="bpcadmin"
BPC_USER="bpcuser"
BPC_ADMIN="bpcadmin"

# Benutzer-Daten
BPC_USER_FIRSTNAME="BPC"
BPC_USER_LASTNAME="User"
BPC_USER_EMAIL="bpcuser@example.com"

BPC_ADMIN_FIRSTNAME="BPC"
BPC_ADMIN_LASTNAME="Admin"
BPC_ADMIN_EMAIL="bpcadmin@example.com"

# Redirect-URL für den Client
REDIRECT_URL="http://localhost*"

# Funktion zur Eingabe von Benutzername und Passwort
read -p "Gib den Keycloak Admin Benutzernamen ein: " ADMIN_USER
read -s -p "Gib das Keycloak Admin Passwort ein: " ADMIN_PASSWORD
echo ""

# Abrufen eines Tokens vom Keycloak-Server
TOKEN=$(curl -s \
  -d "client_id=admin-cli" \
  -d "username=$ADMIN_USER" \
  -d "password=$ADMIN_PASSWORD" \
  -d "grant_type=password" \
  "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" | jq -r .access_token)

# Prüfen, ob das Token erfolgreich abgerufen wurde
if [ -z "$TOKEN" ]; then
  echo "Fehler beim Abrufen des Tokens. Überprüfe Benutzername/Passwort und Keycloak-URL."
  exit 1
fi

# Realm "bpc" erstellen mit Internationalisierung
# Für Login Theme die folgende Zeile mit aufnehmen
# "loginTheme": "theme-id",
echo "Erstelle den Realm '${NEW_REALM}' mit Login-Theme 'foo-theme' und Internationalisierung..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "realm": "'"${NEW_REALM}"'",
    "enabled": true,
    "internationalizationEnabled": true,
    "supportedLocales": ["en", "de"],
    "defaultLocale": "en"
  }'

# Client "bpc" erstellen
echo "Erstelle den Client '${NEW_CLIENT}' im Realm '${NEW_REALM}' mit Redirect-URL '${REDIRECT_URL}'..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/clients" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "'"${NEW_CLIENT}"'",
    "secret": "'"${CLIENT_SECRET}"'",
    "enabled": true,
    "redirectUris": ["'"${REDIRECT_URL}"'"],
    "directAccessGrantsEnabled": true
  }'

# Realm-Rolle "bpcadmin" erstellen
echo "Erstelle die Realm-Rolle '${NEW_ROLE}'..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/roles" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "'"${NEW_ROLE}"'"
  }'

# Benutzer "bpcuser" erstellen
echo "Erstelle den Benutzer '${BPC_USER}'..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "'"${BPC_USER}"'",
    "firstName": "'"${BPC_USER_FIRSTNAME}"'",
    "lastName": "'"${BPC_USER_LASTNAME}"'",
    "email": "'"${BPC_USER_EMAIL}"'",
    "enabled": true,
    "credentials": [{
      "type": "password",
      "value": "'"${BPC_USER}"'",
      "temporary": false
    }]
  }'

# Benutzer "bpcadmin" erstellen
echo "Erstelle den Benutzer '${BPC_ADMIN}'..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "'"${BPC_ADMIN}"'",
    "firstName": "'"${BPC_ADMIN_FIRSTNAME}"'",
    "lastName": "'"${BPC_ADMIN_LASTNAME}"'",
    "email": "'"${BPC_ADMIN_EMAIL}"'",
    "enabled": true,
    "credentials": [{
      "type": "password",
      "value": "'"${BPC_ADMIN}"'",
      "temporary": false
    }]
  }'

# Benutzer-ID des Benutzers "bpcadmin" abrufen
BPC_ADMIN_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/users?username=${BPC_ADMIN}" \
  -H "Authorization: Bearer $TOKEN" | jq -r '.[0].id')

# Rollen-ID der Rolle "bpcadmin" abrufen
ROLE_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/roles/${NEW_ROLE}" \
  -H "Authorization: Bearer $TOKEN" | jq -r '.id')

# Rolle "bpcadmin" dem Benutzer "bpcadmin" zuweisen
echo "Weise die Rolle '${NEW_ROLE}' dem Benutzer '${BPC_ADMIN}' zu..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/users/${BPC_ADMIN_ID}/role-mappings/realm" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "id": "'"${ROLE_ID}"'",
      "name": "'"${NEW_ROLE}"'"
    }
  ]'

# Abrufen der Scope-ID für "profile" im Realm "bpc"
echo "Rufe die Scope-ID für 'profile' im Realm '${NEW_REALM}' ab..."
PROFILE_SCOPE_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/client-scopes" \
  -H "Authorization: Bearer $TOKEN" | jq -r '.[] | select(.name == "profile") | .id')

# Prüfen, ob die Scope-ID für "profile" gefunden wurde
if [ -z "$PROFILE_SCOPE_ID" ]; then
  echo "Fehler: Der Scope 'profile' wurde im Realm '${NEW_REALM}' nicht gefunden."
  exit 1
fi

# Mapper "Impersonator User ID" zum "profile" Scope hinzufügen
echo "Füge dem Scope 'profile' den Mapper 'Impersonator User ID' hinzu..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/client-scopes/${PROFILE_SCOPE_ID}/protocol-mappers/models" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Impersonator User ID",
    "protocol": "openid-connect",
    "protocolMapper": "oidc-usersessionmodel-note-mapper",
    "config": {
      "user.session.note": "IMPERSONATOR_ID",
      "id.token.claim": "true",
      "introspection.token.claim": "true",
      "access.token.claim": "true",
      "claim.name": "impersonator.id",
      "jsonType.label": "String"
    }
  }'

# Mapper "Impersonator Username" zum "profile" Scope hinzufügen
echo "Füge dem Scope 'profile' den Mapper 'Impersonator Username' hinzu..."
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${NEW_REALM}/client-scopes/${PROFILE_SCOPE_ID}/protocol-mappers/models" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Impersonator Username",
    "protocol": "openid-connect",
    "protocolMapper": "oidc-usersessionmodel-note-mapper",
    "config": {
        "user.session.note": "IMPERSONATOR_USERNAME",
        "id.token.claim": "true",
        "introspection.token.claim": "true",
        "access.token.claim": "true",
        "claim.name": "impersonator.username",
        "jsonType.label": "String"
    }
  }'

echo "Fertig!"

configuration script [WARNING]

Running this script is at your own risk. No warranty is provided for its functionality.

The script sets an insecure secret for the client. This should never be used in production environments.

Providing Keycloak Health Checks

Keycloak offers a management interface with health checks. The health check endpoints are available when the environment variable KC_HEALTH_ENABLED is set to the value true. The management interface is typically served on Port 9000; the health check endpoints are /health/live, /health/ready, /health/started, and /health.

If you want to set up the Docker container with the health check endpoints as described in the section “ Script for Automatic Setup,” you must include the arguments -p 9000:9000 and -e KC_HEALTH_ENABLED=true.

After setup, as described in “Configuring the Identity Provider,” you can set the health check URL (e.g., http://localhost:9000/health/ready) and query it via the status API.


Keywords: