Keycloak brokering with second Keycloak IdP

255 views Asked by At

I start telling I am not an expert in this field so It is first times I am dealing with that stuffs. I am mounting an architecture composed by 4 actors:

  • A Keycloak that will operate as Identity Provider (IdP). This will be connected with an LDAP directory to manage all the identities of the system. To distinguish it from now on I will call it Keycloak_1 (on port 8080);
  • A Keycloak that will act as broker. I will call it Keycloak_2 (on port 9000). I used the mentioned app only to get Authorization token for my application. The idea (in the future) is to have multiple IdP (such as Keycloak_1) and a single broker to manage the identity from different tenants. I plugged Keycloak_1 to Keycloak_2 using the section Identity provider (as shown in photo, activating also the settings of this tutorial https://www.keycloak.org/docs/latest/server_admin/#retrieving-external-idp-tokens); IdP ssetup Keycloak
  • The third actor is an API GW, namely Apache APISIX, that can be connected to Keycloak via a native plugin (authz-keycloak: https://apisix.apache.org/docs/apisix/plugins/authz-keycloak/). In this plugin I want to setup as token endpoint the one from Keycloak_2;
  • The last actor is the resource to be protected, i.e. a micro service accessible via REST API;

The flow I want to follow is that. I want that the user is able to connect Keycloak_1 to authenticate itself. After authentication he is able to send POST requests as the following and receive a token:

curl --location 'http://KEYCLOAK_1:8080/realms/REALM_1/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=TEST' \
--data-urlencode 'username=dummy1' \
--data-urlencode 'password=dummy1' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_secret=SECRET' 

**RESPONSE**:
{
    "access_token": "TOKEN_KEYCLOAK_1",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "TOKEN",
    "token_type": "Bearer",
    "not-before-policy": 0,
    "session_state": "c63db133-d61c-426d-b0fe-902fb1b019c1",
    "scope": "profile email"
}

After that, I want to use the token received before by Keycloak_1 (TOKEN_KEYCLOAK_1) and use it to make a similar POST request to Keycloak_2 and receive an AuthZ token (TOKEN_KEYCLOAK_2). The token TOKEN_KEYCLOAK_2 will be given to the API GW to get the resource needed, if the user is trusted, as follow:

curl --location 'http://API_GW/test1' \
--header 'Authorization: Bearer TOKEN_KEYCLOAK_2'

It is important to point that, users that are authenticated in Keycloak_1, are recognized from Keycloak_2 (see image below), but they are not registered to Keycloak_2 (if I try to login without using the sign-in of Keycloak_1 I am not able to enter). IdP linked account

My questions are, if it is possible to complete this flow of operations, if I am doing something wrong, or the if process is lacking of some steps.

1

There are 1 answers

0
Gary Archer On

That's a very standard setup, though the broker is called an authorization server (AS). The way it works is that your apps and APIs only interact with the AS:

  • Client runs a code flow against the AS
  • AS runs another code flow against the IDP
  • IDP issues tokens to the AS
  • AS issues tokens to the client
  • Client sends access token to the REST API
  • REST API downloads token signing public key from AS to validate the access token

One key point is that the client and API never interact with the IDP. Another is that you cannot do this with the password flow, which should not be used.

This may sound complicated but it is just a deployment and configuration job. The code you write will be small. My blog post shows how this type of setup is put together. You would need to translate that to Keycloak:

  • The IDP is configured as an OpenID Connect authentication method in the AS
  • The AS is configured as a client of the IDP