Securing your MuleSoft APIs with OAuth2 using KeyCloak
By Karim DJAAFAR Tech Lead JASMINE CONSEIL
In this blog we will demonstrate on how we can Implement SSO using identity and access management solution Keycloak with MuleSoft Anypoint Platform.
Pre-requisites
- Identity Provider instance available
- Access to Anypoint Platform
- A MuleSoft Demo app
- RAML specification corresponding to the MuleSoft application (publication of the specification on Exchange)
Configuring the Identity Provider (Keycloak)
Keycloak offers a broad set of features, like SSO, authentication and authorization, social login, multi-factor authentication, and centralized user management.
I suggest you to check before reading this post the official documentation to get all the details about this popular SSO solution.
I will suppose that you have already installed Keycloak in your target environment of choice using Docker or directly by extracting the last stable release.
You will after successful installation, create a new Realm by clicking on the Existing Realm Master > Add Realm then naming it mule as showed bellow:
In Keycloak, a Realm is a logical partitioning and isolation unit that helps separate different applications, users, and configurations.
In the Reaml mule create a new client for our MuleSoft application.
In the left pane click on Clients > Create
In Keycloak, a “client” represents an application or service (web application, mobile application, API service) that wishes to use the authentication and authorization features provided by Keycloak
Give a name to the client for exemple mule-client, choose openid-connect protocol and click on save:
Once the client is created, we are redirected to the client configuration page, Settings.
Configure the Access Type in “confidential” mode and save, without forgetting to fill in the mandatory field “Valid Redirect URIs”.
The Valid Redirect URIs field is a valid URI pattern a browser can redirect to after a successful login, here it is set to the URL corresponding to the host of your Keycloak instance
The “Confidential” mode is similar to the “Public” mode, but it adds an additional level of security by using a shared secret between the client and the authorization server (Keycloak). Meanwhile clients using Bearer Only mode use their token to access protected resources without directly interacting with Keycloak for authentication (i.e. these clients are acting as API services or have already obtained an access token from another server)
Notice that the the Credentials view is activated as a result of the “bearer-only” configuration, click on it and retrieve our client’s secret. It will be used later in the requests sent.
Create a user (if one does not yet exist, otherwise retrieve the credentials of an existing user) by clicking on the tab on the left on Users > Add User
Configuring a Client Provider on Anypoint Platform
Now it is time to configure the client provider on Anypoint Platform.
View OpenID Endpoint Configuration information by clicking Realm Settings > OpenID Endpoint Configuration
Those Keycloak required information will be used for client configuration on Anypoint Platform.
Connect to Anypoint Platform, go to Access Management and click on Client Providers on the left pane, then on Add Client Provider > OpenID Connect Dynamic Client Registration
As a reminder, OpenID Connect (OIDC) is built on the OAuth 2.0 protocol and extends it to provide additional user authentication features
Configure the Identity Provider as follows, using the Endpoint OpenID Configuration information as well as the client secret and client ID (mule-client) previously retrieved and click on Create
Use the following Keycloak configuration to set your Anypoint OpenID Connect configuration:
By Karim DJAAFAR Tech Lead JASMINE CONSEIL
In this blog we will demonstrate on how we can Implement SSO using identity and access management solution Keycloak with MuleSoft Anypoint Platform.
Pre-requisites
- Identity Provider instance available
- Access to Anypoint Platform
- A MuleSoft Demo app
- RAML specification corresponding to the MuleSoft application (publication of the specification on Exchange)
Configuring the Identity Provider (Keycloak)
Keycloak offers a broad set of features, like SSO, authentication and authorization, social login, multi-factor authentication, and centralized user management.
I suggest you to check before reading this post the official documentation to get all the details about this popular SSO solution.
I will suppose that you have already installed Keycloak in your target environment of choice using Docker or directly by extracting the last stable release.
You will after successful installation, create a new Realm by clicking on the Existing Realm Master > Add Realm then naming it mule as showed bellow:
Fig 1 — Adding a Keycloak realm
In Keycloak, a Realm is a logical partitioning and isolation unit that helps separate different applications, users, and configurations.
In the Realm mule create a new client for our MuleSoft application.
In the left pane click on Clients > Create
Fig 2 — Creating a new Client
In Keycloak, a “client” represents an application or service (web application, mobile application, API service) that wishes to use the authentication and authorization features provided by Keycloak
Give a name to the client for example mule-client, choose openid-connect protocol and click on save:
Fig 3 — Adding a new client with openid-connect protocol
Once the client is created, we are redirected to the client configuration page, Settings.
Configure the Access Type in “confidential” mode and save, without forgetting to fill in the mandatory field “Valid Redirect URIs”.
Fig 4 — Configure Access type
The Valid Redirect URIs field is a valid URI pattern a browser can redirect to after a successful login, here it is set to the URL corresponding to the host of your Keycloak instance
The “Confidential” mode is similar to the “Public” mode, but it adds an additional level of security by using a shared secret between the client and the authorization server (Keycloak). Meanwhile clients using Bearer Only mode use their token to access protected resources without directly interacting with Keycloak for authentication (i.e. these clients are acting as API services or have already obtained an access token from another server)
Notice that the the Credentials view is activated as a result of the “bearer-only” configuration, click on it and retrieve our client’s secret. It will be used later in the requests sent.
Fig 5 — Getting the Client’s secret
Create a user (if one does not yet exist, otherwise retrieve the credentials of an existing user) by clicking on the tab on the left on Users > Add User
Fig 6 — Creating a Keycloak user
Configuring a Client Provider on Anypoint Platform
Now it is time to configure the client provider on Anypoint Platform.
View OpenID Endpoint Configuration information by clicking Realm Settings > OpenID Endpoint Configuration
Fig 7 — Configuring the Client Provider for Anypoint
Fig 8 — Configuration settings from Keycloak to be applied to Anypoint
Those Keycloak required information will be used for client configuration on Anypoint Platform.
Connect to Anypoint Platform, go to Access Management and click on Client Providers on the left pane, then on Add Client Provider > OpenID Connect Dynamic Client Registration
Fig 9 — Adding a Client provider inside Anypoint
As a reminder, OpenID Connect (OIDC) is built on the OAuth 2.0 protocol and extends it to provide additional user authentication features
Configure the Identity Provider as follows, using the Endpoint OpenID Configuration information as well as the client secret and client ID (mule-client) previously retrieved and click on Create
Fig 10 — Setting OIDC Provider inside Anypoint with Keycloak (1/3)
Fig 11 — Setting OIDC Provider inside Anypoint with Keycloak (2/3)
Fig 12 — Setting OIDC Provider inside Anypoint with Keycloak (3/3)
Use the following Keycloak configuration to set your Anypoint OpenID Connect configuration:
{ “issuer”:
“http://xxx.yyy.zzz.www:8080/auth/realms/mule",
…
“registration_endpoint”: “http://xxx.yyy.zzz.www:8080/auth/realms/mule/clients-registrations/openid-connect",
…
“authorization_endpoint”: “http://xxx.yyy.zzz.www:8080/auth/realms/mule/protocol/openid-connect/auth",
… “token_endpoint”: “http://xxx.yyy.zzz.www:8080/auth/realms/mule/protocol/openid-connect/token",
…
“introspection_endpoint”: “http://xxx.yyy.zzz.www:8080/auth/realms/mule/protocol/openid-connect/token/introspect",
…
}
xxx.yyy.zzz.www is replaced by your keycloak IP host
Configuring your MuleSoft API
Now it is time to test your Anypoint API using the Keycloak OIDC provider.
Let’s consider the following simple MuleSoft API RAML project which will be used to validate our Keycloak configuration; you can of course use any API that suit your testing purpose:
#%RAML 1.0
title: API Managing Client Profil
version: 1.0
baseUri: http://api.jasmineconseil.com
protocols: [HTTP, HTTPS]
traits:
responseError: !include traits/traitErreur.raml
securitySchemes:
oauth2: !include shema-securite/keycloak-oauth.raml
securedBy: [oauth2]
# Type definition
types:
client: !include types-donnees/client.raml
# API Endpoints
/clients:
description: Lister tous les clients
displayName: Profil Client
get:
is: [responseError]
description: Récupérer les informations du client
responses:
200:
body:
application/json:
type: client[]
example: !include exemples/clients.json
post:
description: Create a new client
body:
application/json:
type: client
example: !include exemples/client.json
responses:
201:
body:
application/json:
example: !include exemples/client.json
/clients/{clientId}:
displayName: Client Profil
put:
is: [responseError]
description: Update customer profile information
body:
application/json:
type: client
example: !include exemples/client.json
responses:
200:
body:
application/json:
example: !include exemples/client.json
delete:
is: [responseError]
description: Delete customer profile information
responses:
204:
description: The customer profile has been successfully deleted.
Regardless of the MuleSoft project launched, it is crucial as a best practice that each MuleSoft project is first generated from its RAML specification (such as the aforementioned project), regardless of its complexity.
This is essential because the RAML specification will serve as the basis for further management of the application in Anypoint’s API Manager.
Now you can import the RAML specification from Design Center into your Anypoint IDE using API Kit:
Register your Mule API at the API Manager level
In this step, we will add the RAML specification of our Application at the API Manager level.
As a recall, to manage your MuleSoft application with the API Manager Anypoint component, it is necessary to provide the specification of the API in question. This specification is in RAML language.
In Anypoint Platform, go to the API Manager level, click on Add API > Add new API.
- Select Mule Gateway and confirm.
Mule Gateway is an API management solution for MuleSoft applications, while the Flex Gateway and Service Mesh are advanced features of Anypoint Runtime Fabric that improve micro-services management in distributed and elastic environments for any kind of APIs
- Search and select our API (previously published on Exchange in my case), then click on next until the end then save:
- Check that your Mule application example (specification-profil-client) is added in the API Manager but not yet registered:
Now we continue registering our Application to the API manager with the Autodiscovery API.
For that you can retrieve the identifiers (Client Id and Client Secret) of your organization in Access Management > Business Groups > <Organization Name>:
That information is required to inform them at the level of our application.
- Open our app in Anypoint Studio
- Click on Window > Preferences > Anypoint Studio > API Manager, enter the Client Id and the Client Secret, click on Validate, then on Apply and Close
- Get the Autodiscovery API in our Application in the Global Configuration Elements :
- Launch your application and return to the API Manager at Anypoint Platform and now check that the application status is green (API Status), notice that the activation can take between 30 seconds and 1 minute depending of your specific configuration and network:
As you can see your API is active inside the API Manager and we can now apply some policies to validate our API settings and Keycloak configuration.
Apply a JWT policy that will use our Configured Keycloak instance
Now that we have registered our application on the API Manager, it is time to apply some JWT policy to it.
- Go to the API Manager and click on our API which will be the subject of JWT font application
- In the left pane click on policies
Click on Add Policies and select the JWT Validation policy and click on Next:
- Configure the JWT validation policy as follows and according your keycloak setting, then click Apply:
{
"issuer": "http://xxx.yyy.zzz.www:8080/auth/realms/mule",
"jwks_uri": "http://xxx.yyy.zzz.www:8080/auth/realms/mule/protocol/openid-connect/certs",
"tls_client_certificate_bound_access_tokens": true
}
Notice here that we have checked “Skip Client Id Verification”.
In fact, when the “Override client ID validation” option is checked (enabled) in the JWT validation policy, client application authentication is only based on OAuth 2.0.
In other words, the Manager API will not validate the identity of the client application (id_client) against the API contract (RAML). Instead, it relies entirely on OAuth 2.0 for authentication and access control.
Testing your JWT Validation Enforcement policy
- Start your Postman or any other API Testing tool and attack the endpoint of an HTTP Listener, in our case http://localhost:8081/api/clients.
We should observe a restriction on the API call:
Dont panick ! This is normal at this step as we have not set any valid token.
We find that the JWT policy works, since access is prohibited due to the lack of Token provision. For this endpoint to return data, we will need to retrieve the token at our Identity Provider Keycloak instance that we have set and then insert it with each API call.
Configure the Client (Postman) for Token Recovery
- Add a new POST request and give it a name. Here we have chosen the Token name (Digital Ocean Server for our example) which will point to the token recovery URL (coming from the IDP Keycloak server).
{
"issuer": "http://xxx.yyy.zzz.www:8080/auth/realms/mule",
"token_endpoint": “http://xxx.yyy.zzz.www:8080/auth/realms/mule/protocol/openid-connect/token",
"tls_client_certificate_bound_access_tokens": true
}
- In the Authorization pane, select OAuth 2.0 and configure as follows:
- In the Body pane, select x-www-form-urlencoded and configure as follows (replace the username and password by the setting that you have done in the Keycloak user in the step before):
- Configure SSL support according to the security status of our IDP server (Keycloak)
If your Keycloak IDP (Identity Provider) server is not secure (HTTPS), it will be necessary to deactivate the Require SSL option in the Login tab at the Realm Settings level of Keycloak. Otherwise, the POST request to retrieve the token will not pass.
- Relaunch the request and retrieve the “access_token“ token in the response part, which validate our Keycloak and Anypoint setting:
Conclusion
In this post we have successfully configured and illustrated the steps to configure our Keycloak as a OIDC client provider for Anypoint and applied a JWT validation policy to secure our API, hope this article will be useful for your specific case!