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);
- 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).
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.
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:
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: