How does the WSO2 API Manager 3.0 and Microgateway 3.0s new Token Revocation Feature Work

Sampath Rajapakse
API Integration Essentials
7 min readJul 7, 2019

What’s the problem this feature addresses?

When the API Microgateway is working with JWT formatted self-contained access tokens, it does not communicate with the WSO2 API Managers’s Key Manager(KM)/STS component for checking the validity of the token. It considers any token with a trusted signature as valid as long as the token is not expired. However, this model becomes a problem when the respective token is revoked by the KM/STS. As a result, there was a requirement for a mechanism where the API Microgateway gets notified when a token is revoked before its expiry.

Specifically Identified Problems

How to send revoked tokens to the Microgateways?

There are few ways to send revoked token to the Microgateway.

  1. Microgateway sends api request to an endpoint in API Manager which in fact retrieves all the revoked token from the database and send in the response.

This approach was abandoned due to the fact this will cause unnecessary huge network traffic.

2. By using publisher-subscriber model, where MG subscribes to a topic and KM publishes revoked token to the topic.

How to persist the revoked tokens in the Microgateways?

There are few ways to persist revoked token in the Microgateway.

  1. By storing only in the revoked token cache.

When Microgateway restarts it will loose all the cached data including revoked token cache. Therefore, if some user sends revoked token after a server restart, MG will accept that revoked JWT token as a valid token.

2. How to resolve this MG server restart issue?

By storing data in a persistent database.There needs to be a third party data persistent storage which stores all these revoked tokens.

3. Can we use a relational database like mysql for this purpose?

Of course, but it will be an unnecessary burden for Microgateway to have a high-weight database. It will defeat the whole purpose in the word “Micro”.

4. So what kind of databases can we use?

Obviously a light weight database which stores data as key-value pair. Also, it would be advantageous if the database it self have a data clean up mechanism, otherwise we need to run a script to clean up the old revoked tokens which are expired.

After considering all these above specific problems, we have come up with following solution.

Solution

Overall Architectural Diagram

Real-time Notifier

Here, WSO2 API Microgateway uses a Publisher- Subscriber model (pub-sub model) where the Security Token Service (STS) and WSO2 API Microgateways are linked using a Message Broker (MB). Whenever a revoke token request is received, the STS publishes a message to the JMS Message Broker. WSO2 API Microgateway has subscribed to the tokenRevocation topic, which is the JMS connection topic. When the JMS connection topic receives a message, the Message Broker propagates the message to the WSO2 API Microgateway servers. When the WSO2 API Microgateway servers receive this message, they will store the revoked tokens in-memory and treat them as revoked tokens. You can not extend the Real-time Notifier to add your own implementation.

Persistent Notifier

In this scenario, WSO2 API Microgateway uses a persistent storage mechanism to link the Security Token Service (STS) and the WSO2 API Microgateway servers. Whenever a token revoke request is received, the STS publishes a message to the persistent storage. When a new WSO2 API Microgateway server spins up, it pulls the list of revoked tokens from the persistent storage, and stores them in the revoked jti (JWT ID) cache. The latter mentioned process only takes place once. just at the startup. By default, WSO2 API Microgateway uses a etcd server as its persistent storage when working with persistent notifications. However, unlike when using the real-time notifications, when using the persistent notifications, you can use any persistent storage and a custom implementation.

How to enable this feature?

  1. Navigate to <APIM_HOME>/repository/conf/api-manager.xmlfile and enable the following configuration.

2. Navigate to the <MGWTK_HOME>/resources/conf/micro-gw.conf file and enable the following configuration.

3. If you need to change the topic name at API Manager side, then change the topic physicalName value in <APIM_HOME>/repository/conf/jndi.propertiesconfiguration.

Let’s try out !

  1. Configure the persistent storage(etcd-v2).
  • Use following commands to create a self-signed certificate for etcd server.
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out server.pemopenssl x509 -outform der -in server.pem -out server.crt
  • Add the self signed certificate(server.crt) to the ballerinaTruststore.p12 in the Micro-Gateway Project and to the client-truststore.jks in API Manager.
  • Install etcd server.
brew install etcd
  • Start etcd server with HTTPS enabled
etcd — name infra0 — data-dir infra0 — cert-file=<PATH_TO_CERT>/server.crt — key-file=<PATH_TO_CERT>/server.key — advertise-client-urls=https://localhost:2379 — listen-client-urls=https://localhost:2379
  • Create a root user with username and password.
curl — cacert <PATH_TO_CERT>/server.crt https://localhost:2379/v2/auth/users/root -XPUT -v -d ‘{“user” : “root”, “password”: “root”}’
  • Enable basic authentication.
curl — cacert <PATH_TO_CERT>/server.crt https://localhost:2379/v2/auth/enable -XPUT -v
  • Use the following curl command to create a directory in etcd to store revoked jti’s. ( Ex: jti)
curl — cacert <PATH_TO_CERT>/server.crt https://127.0.0.1:2379/v2/keys/jti -XPUT -d dir=true

please note that that the persistent notifiers hostname does include the directory name which you created. Therefore, update the configurations accordingly if you have used any other word than “jti”.

Ex: https://127.0.0.1:2379/v2/keys/<directory_name>

2. Start WSO2 API Manager.

By going to the <API-M_HOME>/bin directory using the command-line and then executing wso2server.bat (for Windows) or wso2server.sh (for Linux.)

3. Deploy the sample API in Publisher.

API Publisher 2.6 UI

4. Initialize an API Microgateway project.

Navigate to a preferred folder where you want to create the Microgateway project. Thereafter, run the following command.

micro-gw init <project-name>

5. Build the WSO2 API Microgateway project.

Navigate to the <MGW_HOME>/bin directory and run the following command.

micro-gw build <project-name>

This creates an executable file (/<project-name>/target/<project-name>.balx) that you can use to expose the API via WSO2 API Microgateway.

6. Start WSO2 API Microgateway.

To enable ballerina login use the following startup command,

gateway -e b7a.log.level=TRACE <path-to-MGW-executable-file>

you will able to see the following output in the console,

As you can see the Microgateway has successfully retrieved all the revoked tokens from the etcd server and also added to the revoked token cache by persistent notification scenario.

7. Generate a JWT token from API Manager and extract the jti claim.

  • Sign in to the API Store (https://<hostname>:9443/store) with the admin/admin credentials.
  • Create an application with JWT selected as Token Type.
  • Go to Production Keys tab and click Generate Keys to generate a JWT token.
  • Extract the jti claim by using https://jwt.io site.

8. Test by sending a revoke request to API Manager.

curl -k -v -d "token=<jti>" -H "Authorization: Basic <base64-encoded-string>" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/revoke

The following response can be seen via the WSO2 API Microgateway console.

Therefore, it seems now the revoked token has been added to the revoked token map by using real time notification scenario.

Now, what we have to do is invoke the api using this revoked JWT token.

curl -k -i -H "Authorization: Bearer <JWT-token>" https://localhost:9095/pizzashack/1.0.0/menu

you will be able to see following response,

Response in the Microgateway Console
Response to the curl Command

As you can see in the Microgateway console, it has successfully recognized the JWT token in the request as a revoked token. Therefore, as the response you will receive 401 (Un-authorized request) error.

In this post i have only touched the default behaviour of this token revocation feature. As for the next posts in this token revocation feature series, i will address how to extend this default behaviour and how to add custom logic instead of default implementation and how to write a interceptor to key manager to add any post token revocation logic in WSO2 Api Manager.

Please note that this feature only will fully available from API Manager 3.0 and Microgateway 3.0 releases.

--

--