Configure OpenID Connect (OIDC) authentication with Keycloak

This topic describes how to configure Keycloak as Identity provider for OpenId Connect to login in deploy and protect REST APIs using Bearer Token Authorization.

Keycloak

Keycloak is an open source Indentity and Access management solution. It is based on popular standards such as Security Assertion Markup Language (SAML) 2.0, OpenID Connect, and OAuth 2.0.

Installation

Hardware requirements, distribution directory structure, and operation mode information can be found at Keycloak documentation website.

We use docker-compose example from https://github.com/keycloak/keycloak-containers/blob/master/docker-compose-examples/keycloak-postgres-jdbc-ping.yml to setup keycloak.

Keycloak default screen

Set up a realm

First, we will create a new realm. On the top left, navigate to Master, open the drop down menu, and click Add realm.

Add realm

Add a new digitalai-platform realm as shown below.

digitalai-platform realm

Realm details

Add roles

We will add different roles in Keycloak as shown below.

Add role

All roles

Add users

We will now add new users in Keycloak. Fill in all fields, such as Username, Email, First Name, and Last Name.

Add user

Select appropriate role mappings for a user.

Map roles

All users

Set up a client

The next step is to create a client in our realm, as shown below.

Add client

Fill in all of the mandatory fields in the client form. Pay attention to Direct Grant Flow and set its value to direct grant. Change Access Type to confidential.

Client details

Direct grant

Select builtin mappers for newly created client.

Client mappers

Make sure that username and groups mapping are present in both id token and access token.

Group mapping

Add new client scope

Next, we have to create a new client scope for REST APIs, as shown below.

Add client scope

Add new protocol mapper

Add a new protocol mapper to add audience information in access token, as shown below.

Add protocol mapper

Set default client scope

Final step is to add client scope deploy-rest-api as default for deploy client, as shown below.

Add default client scope

Copy the client’s credentials which we will be using later.

Client credentials

Set up Digital.ai Deploy

Now let’s configure OpenID Connect (OIDC) authentication for Deploy. Follow the setup process from Deploy OIDC Setup Guide.

Below is our oidc configuration from xl-deploy.conf.

xl {
    security {
        auth {
            providers {
                oidc {
                    loginMethodDescription = "Login using Keycloak"
                    clientId="deploy"
                    clientSecret="ff8a8547-dbe3-4267-ae55-9822d6f02499"

                    issuer="http://localhost/auth/realms/digitalai-platform"
                    redirectUri = "http://localhost:4516/login/external-login"
                    postLogoutRedirectUri = "http://localhost:4516/oauth2/authorization/xl-deploy"

                    rolesClaimName="groups"
                    userNameClaimName="preferred_username"
                }
            }
        }
    }
}

Test your set up

First we need to assign appropriate permissions in Deploy for users present in Keycloak. The OIDC users and roles are used as principals in Deploy that can be mapped to Deploy roles. Login with internal user and map roles with OIDC roles, as shown below.

Deploy role

Assign appropriate global permissions, as shown below.

Deploy permission

Open your deploy url in browser and you should be redirected to Keycloak login page.

Deploy login

Now, Enter the credentials of any user created on keycloak.

After login

Test public REST APIs

Generate an access token using password grant type flow for your client. You can use curl command, as show. below.

curl -L -X POST 'http://localhost/auth/realms/digitalai-platform/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=deploy' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_secret=ff8a8547-dbe3-4267-ae55-9822d6f02499' \
--data-urlencode 'scope=deploy-rest-api' \
--data-urlencode 'username=alice' \
--data-urlencode 'password=alice'

Alternatively, we can use REST API tools like Postman, as shown below.

Postman request

The response would be a valid JWT Token:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUI...Daw3OcJ2aPFzXY1cpHmH0W36TTfgfYGHgnDqB4w",
    "expires_in": 600,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldU...YlO6MzdDRhx_J3WShGXesjOmhY",
    "token_type": "bearer",
    "not-before-policy": 0,
    "session_state": "d2c14e42-9bc3-4416-9bea-02aa6adb770e",
    "scope": "profile deploy-rest-api email"
}

We can now pass access_token as Bearer Token to authenticate Release public REST APIs.

curl -L -X GET 'http://localhost:4516/deployit/repository/v3/query?page=0&resultsPerPage=10&parent=Applications' \
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUI...Daw3OcJ2aPFzXY1cpHmH0W36TTfgfYGHgnDqB4w'