IBM Security Verify

 View Only

OAuth: JWT as an Access Token

By Sumana Narasipur posted Thu July 19, 2018 12:00 AM

  

The OAuth 2.0 specification does not go into great detail about token formats. 


“Access tokens can have different formats, structures, and methods of utilization (e.g., cryptographic properties) based on the resource server security requirements.”

On IBM Security Access manager (ISAM) access tokens issued are a short opaque string used as a reference to a centralized repository. In some instances it can be advantageous to use a pass-by-value tokens which contain all necessary claims encapsulated in a cryptographic token which can then be validated locally by a resource server.

My colleague Shane Weeden has produced an article on this pattern previously, however this was using an earlier release of ISAM, which did not have a JWT STS module, support for custom tokens as part of the OAuth authorization server, or OAuth token introspection.

The steps in this article will show how you can configure ISAM to use a pass-by-value strategy for access tokens for lateral scalability.

JWT Access Token Creation and Consumption


The examples and code provided in this article can be used with  the implicit flow, the authorization code flow, and resource owner password credential grant. Additionally the code will include two consumption patterns for the JWT access tokens, the OAuth introspection endpoint and the Web Reverse Proxy oauth-auth method of authentication.

In order to achieve JWT access tokens the following need to be augmented. Here is a list of what and how

  • Access token issuing from /authorize – Via the pre-token mapping rule.
  • Access token issuing from /token – Via the pre-token mapping rule
  • Access token validation in /introspect – via the pre-token mapping rule and providing a validation decision
  • Access token validation in the reverse proxy – via defining a custom STS chain and proxy configuration

JWT Token format


The JWT token format used in this article is a simple base. Including only the following claims.

{
  "exp": 1531807284,
  "iat": 1531803684,
  "sub": "testuser",
  "aud": "example_client",
  "scope": [
    "scope1",
    "scope2"
  ]
}


The format is intended to cover:

  • who the token was issued to  – aud
  • on behalf of who the token is for  –  sub
  • what the token was granted – scope
  • for how long the token is valid – exp
  • when the token was created – iat


This format can be extended to include any additional claims necessary.

Necessary Components


In order to configure an OAuth definition to issue pass by value JWT tokens several components and resources will be used:

  • ISAM added the ability to build custom tokens in 9.0.2.0 with one of the primary intents for consumption being a JSON Web Token as access token.
  • ISAM 9.0.2.0 also brought the addition of a JWT STS Module.
  • In an earlier article, I highlighted the ability to call an STS chain from a javascript context for high performance situations.


It is assumed that there is a configured OAuth definition and reverse proxy as a starting point.

This solution makes use of the LocalSTSClient, which was added in version 9.0.5.0.

STS Chains


The first thing to do is to configure the JWT STS chains. These are used to both create and validate the JWTs. The chains are:

JWT Access token creation:

STSUU(validate) -> JWT(issue)

JWT Access token validation:

JWT(validate) -> STSUU(issue).

STS Chain configuration


Configuring STS chains is a two step process. First you must configure the chain template. This template is what outlines the order and mode of the modules in the chain. This video shows the configuration of both chains.



After configuring the chain templates, the chains themselves have to be configured.

We have several fields we need to cover here:

  • Chain mode – we will use validate mode http://schemas.xmlsoap.org/ws/2005/02/trust/Validate
  • Issuer and appliesTo addresses. We will use the value urn:jwt:issue and urn:jwt:validate for both of these fields for each chain respectively.
  • Module properties – we need to configure how the JWT is validated and issues. We’ll use RS256 signing, and use the rt_profile_keys / server certificate. Note, At this point, if necessary JWT encryption could be used to obfuscate the claims from the client.


This video covers configuring the chain instances:



Additional examples of configuring STS chains can be found in the Federation Cookbook.

Mapping rules


The next step in producing JWT Access tokens is to upload the mapping rules to the appliance. There are two which need to be done initially, the jwt_at_common.js and the jwt_at_pre.js files. The contents of the files are available here. Please note that when uploading the mapping rules, you need to ensure the correct names are used. These rules make use of mapping rule includes, which depend on the correct names for the files.

Now that the rules are uploaded, update your oauth pre-token mapping rule to include the following snippet:

importMappingRule("jwt_at_pre");


This will call our JWT Access token logic.



This configures the OAuth definition for all the operations needed to issue JWT access tokens. You can see now, that instead of an opaque token being used, a JWT is issued, containing necessary claims to validate the token. Additional claims could be included. 



Token introspection


With the above mapping rules, token introspection will now also be possible. Be sure to check the value of only_allow_conf_client_introspect in the pre-token rule and must_client_own_token_introspect in the post token rule if you are using a client which is not confidential or trying to introspect with a client which is different to the audience of the token. 



Reverse proxy authentication with OAuth


Authentication to the reverse proxy with an oauth token in the Bearer header makes use of the STS as well. However in this instance, the usual STS chain cannot be used (The client cannot be looked up, so the mapping rule cannot run). So instead, we will point the reverse proxy to a new STS chain. Firstly there is an additonal mapping rule jwt_at_validate.js to be uploaded. Then a new STS chain needs to be configured with just the module Default Map. The lookup details for this chain use the hard coded issuer address of urn:ibm:ITFIM:oauth20:token:bearer and in our example we will use the appliesTo of urn:jwt:webseal the request type is once again http://schemas.xmlsoap.org/ws/2005/02/trust/Validate. The chain properties should use the mapping rule jwt_at_validate. Once the chain has been configured, the [oauth] stanza must be updated, the entry default-fed-id needs a value which matches the appliesTo of the chain; urn:jwt:webseal. The configuration is performed in this video:



Once the chain and the reverse proxy are configured, we can go ahead and make a request to a protected resource including a bearer token. 


 

The following has now been configured to achieve a pass-by-value access token stratergy:

  • Custom access_token’s are being built in the OAuth pre-token mapping rule.
  • Custom validation logic is being performed in the OAuth pre-token mapping rule for introspection
  • JWT Issue and Validate chains have been configured
  • An OAuth-authentication STS Chain has been configured and the reverse proxy updated to use the chain.

0 comments
65 views

Permalink