Integrating Keycloak as a Third Party Key Manager with WSO2 API Manager

Organizations who already own Identity and Access Management solutions would want to keep it and use it as a third party key manager integrated with WSO2 API Manager to handle clients, security and Oauth tokens. API Store communicates with the Key Manager to create/manage Oauth applications/clients, generate Oauth tokens and validate the tokens upon API invocations using the generated tokens. It is a decoupled highly cohesive component which takes care of Oauth client management and the key management.

Writing a custom Key Manager for WSO2 can be simply done by extending the following class in the API Manager.

org.wso2.carbon.apimgt.impl.AbstractKeyManager

Mainly the following methods needs to be overridden and implemented in this class. The implementation can be simply done by invoking the corresponding APIs in the third party Key Manager product that needs to be integrated. Refer to the API guides provided by each product and look for relavant APIs. Make sure that from within each method the required return object types are returned with the required fields populated in order to API Store UIs to be rendered correctly.

  • createApplication : Used to create an oauth application / provision an oauth client in the third party key manager.
  • updateApplication: Update the client created above in create application.
  • deleteApplication: delete a created oauth application.
  • retrieveApplication: Retrieving the Oauth application details from the third party key manager to be shown in the API store under applications.
  • getNewApplicationAccessToken: Generating a new access token to be shown in the API store after clicking ‘Generate Keys’ and ‘Regenerate Keys’.
  • getTokenMetadata: Implementing this method is really important since it is invoked during the token validation phase upon an api invocation. Most Oauth compliant IAM products provide an introspection endpoint to check the token validity and scopes.

I will explain how Keycloak which is an open source IAM solution can be integrated with WSO2 APIM in this article. This article is for Keycloak 9.0.0 and API Manager 2.6.0 versions.

The source code for this Key Manager Implementation can be found here.

First we need to configure Keycloak. Keycloak has an admin REST API which is secured with tokens and requires a user with admin previledges and a client to be able to invoke it. We will first look into how this can be achieved.

  1. Go to the Keycloak download page and download the Standalone server distribution.
  2. After Downloading extract the keycloak distribution to a location in the server. This extracted directory will be referred to as KEYCLOAK_HOME :
  • Go to the <KEYCLOAK_HOME>/bin directory.
  • Start up the Keycloak server by executing ./standalone.sh

3. Provide credentials for an admin account which will be used to login to the management console. After the user account is successfully created. Login to the Administrator Console by following the link.

Create a new user and login

4. Create a new realm :

  • On the top of the left side bar menu, hover over ‘Master’ which corresponds to the master realm. Click on the Add Realm button which appears.
  • Provide a name (e.g. apim) for the realm and click create.
  • A new realm will be created and you will be redirected to a settings page.
realm settings

5. Create a client and an admin user in the newly create realm to be used for admin API invocations.

  • From the left menu click on Clients. Click the Create button on the upper right had side. Provide the Client Id as apim-client and the Client Protocol as openid-connect.
create client
  • From the left menu click on Users. Click the Add User button on the upper right had side. Provide the username as apim-user and provide apim-password as password on the password tab. Make sure to turn off the Temporary field value.
Crete user
Provide password
  • Move to the Role Mappings tab and from the Client Role drop down select realm-management. Select all the roles and click on add selected.
Role mappings

Now the Keycloak client and the user is setup appropriately.

Let’s move forward configuring the WSO2 API Manager and testing the integration.

6. Download latest apim-keymanager-keycloak-x.x.x.jar from here.

7. Copy that JAR file into the <API-M_HOME>/repository/components/lib directory.

8. Uncomment the <APIKeyManager> parameter in the <API-M_HOME>/repository/conf/api-manager.xml file. Change the values as follows to support the third-party API.

<APIKeyManager>
<KeyManagerClientImpl>org.wso2.keycloak.client.KeycloakClient</KeyManagerClientImpl>
<Configuration> <keycloakInstanceUrl>http://localhost:8080</keycloakInstanceUrl>
<keycloakRealmName>apim</keycloakRealmName>
<client_id>apim-client</client_id>
<username>apim-user</username>
<password>apim-password</password>
</Configuration>
</APIKeyManager>

9. Comment out the grant types which are not supported by Keycloak by commenting out the ones other than implicit, authorization_code client_credentials, password under the SupportedGrantTypes section in the identity.xml file which can be found under <APIM_HOME>/repository/conf/identity directory

You have connected WSO2 API Manager with a third-party Keycloak IAM server. Let’s see how WSO2 API Manager creates OAuth clients in Keycloak, when applications are registered in the API Store.

10. Start WSO2 API Manager and sign in to the WSO2 API Store.

11. Create an application call keycloakClientApp. Make sure to select the Token Type as OAuth.

Add application

12. Register an OAuth client in the Keycloak and generate the access token.

Generate Keys

13. In order for us to be able to use the WSO2 API Manager /token endpoint to generate tokens, update the token endpoint in the <API-M_HOME>/repository/deployment/server/synapse-configs/default/api/_TokenAPI_.xml file accordingly.

e.g. http://localhost:8080/auth/realms/apim/protocol/openid-connect/token

Obtain a token from the OAuth Provider. Replace <ConsumerKey:ConsumerSecret> with the Base64 encoded ConsumerKey:ConsumerSecret of the client application you just created.

curl -k -d "grant_type=client_credentials&scope=test" -H "Authorization: Basic <ConsumerKey:ConsumerSecret>" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

Copy the access_token value from the response JSON. This will be the token which will be used to invoke the API. Next we will validate the generate token.

14. Sign in to the API Publisher and deploy the sample API (PizzaShackAPI), if you haven’t done so already

Deploy API

15. Select the application you created earlier from the drop down menu and click Subscribe.

Subscribe to API

16. Invoke the API using the token obtained as follows.

curl -k -X GET --header 'Accept: application/json' --header 'Authorization: Bearer eyJraDH2LexQssMURzB56q78dmRa0NmDpH1o2FGYrVxCLeNcypJq6OlrzXw7N_R9H1f1OwH5GnT3pHssXjblr4qBKunIj6hRA0-lqHcwq3hcxusb2wgnUta_xudrUfXFn9bQXb5pkg' 'https://172.17.0.1:8243/pizzashack/1.0.0/menu'

You will ge the following response.