Using JWT OAuth tokens

You're viewing Apigee X documentation.
View Apigee Edge documentation.

This topic explains how to generate, verify, and refresh JWT access tokens using the OAuthV2 policy.

Introduction

The JWT operations allow the OAuthV2 policy to generate, verify, and refresh access tokens that conform to the JWT token standard. JWTs are commonly used to share claims or assertions between connected applications. Issuing OAuthV2 access tokens in JWT format is an alternative to issuing traditional opaque string access tokens.

When configured for JWT, the OAuthV2 policy generates and returns a Base64-encoded JWT that consists of a header, a payload, and a signature separated by dots. For example:

Figure 1: JWT serialized format consisting of header, payload, and signature separated by dots.

The encoded contents of these elements depend on how you configure the OAuthV2 policy. In the policy, you specify such parameters as the signing algorithm and payload elements like subject and name. For example, the header might decode as {"alg":"HS256","typ":"JWT"}, and the payload might decode as: {"sub":"1234567890","iat":1516239022}.

The header specifies a type (always JWT) and the algorithm used to sign the JWT. Apigee supports RSA and HMAC algorithms: HS(256,384,512) and RS(256,384,512).

Payload

The payload consists of claims about the entity. Some claims must be provided by you in the policy configuration, while others are automatically generated by Apigee. We support the following claims:

Claim Description Provided by
Issuer The token issuer. This value is set as follows: (http|https)://{domain-name}/{proxy-basePath}. For example: https://www.google.com/auth/v2. Apigee
Subject Either the Client ID or the ID of the resource owner (in the case of password or authorization grant types). If the appEndUserId parameter is provided in the request, that value is used as the resource owner ID. You can control where this value is set using the <AppEndUser> element of the OAuthV2 policy. API developer
Unique ID Represented as a UUID-backed random string to uniquely identify the token. Apigee
Expiry time The time during which the token is valid. The value is expressed in epoch time (in seconds). Apigee
Creation time The time the token was created. The value is expressed in epoch time (in seconds). Apigee
Client_Id The unique identifier of the client application. API developer
Scope The OAuth scope assigned to the token. See also Working with OAuth scopes. API developer

Signature

The signature is generated using the encoded header, payload, secret/private key, and the algorithm. The signature is used to ensure that the contents of the token have not been tampered with.

For more information about JWT, see the JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens.

Prerequisites

This document assumes that you understand how to generate and verify OAuthV2 access tokens using the OAuthV2 policy. Whether you use the JWT operations or the traditional operations that create opaque string tokens, the basic use of the OAuthV2 policy is the same. You can use JWT access tokens with all of the supported OAuthV2 grant types. See also Introduction to OAuth 2.0.

Generating a JWT access token

Use the GenerateJWTAccessToken and GenerateJWTAccessTokenImplicitGrant operations to generate a JWT access token with the OAuthV2 policy. These operations are similar to the policy's traditional GenerateAccessToken and GenerateAccessTokenImplicitGrant operations. The main difference is that the JWT operation returns a JWT-formatted access token instead of an opaque string token. See also Requesting access tokens and authorization codes.

The following examples show how to use these operations in the OAuthV2 policy. The examples use the client_credentials grant type; however, you can use any of the supported grant types with these operations.

Generating a JWT token with an HMAC algorithm

To generate a token with the HMAC (HS256/HS384/HS512) algorithm, you must provide the <SecretKey> and <Algorithm> elements (they are required). The following example shows a policy configured to generate a JWT token with the HMAC algorithm.

<OAuthV2 name="generate-policy">
  <Operation>GenerateJWTAccessToken</Operation>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GenerateResponse enabled="true"/>
  <Algorithm>HS512</Algorithm>
  <SecretKey>
    <Value ref="propertyset.MyPropSet.mysecret"></Value>
  </SecretKey>
  <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn>
</OAuthV2>

Generating a JWT token with an RSA algorithm

To generate a token with the RSA (RS256/RS384/RS512) algorithm, you must provide the <PrivateKey> and <Algorithm> elements (they are required). element. The following example shows a policy configured to generate a JWT token with the RS512 algorithm.

<OAuthV2 name="generate-policy">
  <Operation>GenerateJWTAccessToken</Operation>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GenerateResponse enabled="true"/>
  <Algorithm>RS512</Algorithm>
  <PrivateKey>
    <Value ref="propertyset.MyPropSet.mysecret"></Value>
  </PrivateKey>
  <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn>
</OAuthV2>

Generating a JWT token implicit grant type

The GenerateJWTAccessTokenImplicitGrant operation generates a JWT access token using the implicit grant type. It automatically gives the token the implicit grant type; therefore, the <SupportedGrantTypes> element is not required. Note that the <PrivateKey> and <Algorithm> elements are required. See also Requesting the implicit grant type.

<OAuthV2 name="generate-policy">
  <Operation>GenerateJWTAccessTokenImplicitGrant</Operation>
  <GenerateResponse enabled="true"/>
  <Algorithm>RS512</Algorithm>
  <PrivateKey>
    <Value ref="propertyset.MyPropSet.mysecret"></Value>
  </PrivateKey>
  <ExpiresIn ref="kvm.oauth.expires_in">3600000</ExpiresIn>
</OAuthV2>

Verifying a JWT access token signed with an HMAC algorithm

Use the VerifyJWTAccessToken operation to verify a JWT access token with the OAuthV2 policy. This operation is similar to the policy's traditional VerifyAccessToken operation.

The following example shows how to configure the OAuthV2 policy to verify a JWT token that was signed with the HS512 algorithm. Note that the policy requires the <SecretKey> value that was used to sign the JWT.

<OAuthV2 name="verify-policy">
  <Operation>VerifyJWTAccessToken</Operation>
  <Algorithm>HS512</Algorithm>
  <SecretKey>
    <Value ref="propertyset.MyPropSet.mysecret"></Value>
  </SecretKey>
  </OAuthV2>

Verifying a JWT access token signed with an RSA algorithm

Use the VerifyJWTAccessToken operation to verify a JWT access token with the OAuthV2 policy. This operation is similar to the policy's traditional VerifyAccessToken operation.

The following example shows how to configure the OAuthV2 policy to verify a JWT token that was signed with the RS512 algorithm. Note that the policy requires the <PublicKey> value for the private key that was used to encrypt the JWT.

<OAuthV2 name="verify-policy">
  <Operation>VerifyJWTAccessToken</Operation>
  <Algorithm>RS512</Algorithm>
  <PublicKey>
    <Value ref="propertyset.MyPropSet.mysecret"></Value>
  </PublicKey>
  </OAuthV2>

Refreshing an HMAC-signed access token

Use the RefreshJWTAccessToken operation to refresh a JWT access token. This operation is similar to the policy's traditional RefreshAccessToken operation. See also Refreshing an access token.

The following XML sample illustrates how to configure the OAuthV2 policy to refresh a JWT token that was signed with an HMAC algorithm. Note that the <SecretKey> and <Algorithm> elements are required.

The response of the refresh operation is similar to the response of a newly generated token. The refresh operation generates a new JWT token with an updated expiry time, keeping other claims the same.

<OAuthV2 name="RefreshAccessToken">
    <Operation>RefreshJWTAccessToken</Operation>
    <GenerateResponse enabled="true"/>
    <Algorithm>HS512</Algorithm>
    <SecretKey>
      <Value ref="propertyset.MyPropSet.mysecret"></Value>
    </SecretKey>
    <RefreshTokenExpiresIn ref="kvm.oauth.expires_in">3600000</RefreshTokenExpiresIn>
</OAuthV2>

Refreshing an RSA signed JWT access token

The following XML sample illustrates how to configure the OAuthV2 policy to refresh a JWT token that was signed with an RSA algorithm. See also Refreshing an access token.

<OAuthV2 name="RefreshAccessToken">
    <Operation>RefreshJWTAccessToken</Operation>
    <GenerateResponse enabled="true"/>
    <Algorithm>RS512</Algorithm>
    <PrivateKey>
      <Value ref="propertyset.MyPropSet.mysecret"></Value>
    </PrivateKey>
    <RefreshTokenExpiresIn ref="kvm.oauth.expires_in">3600000</RefreshTokenExpiresIn>
</OAuthV2>

Sample response

For both generate and refresh operations, the response body looks similar to the following example. Note that the access_token is represented as a serialized JWT, and the refresh token is a traditional opaque string-format token.

{
  "access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "token_type": "Bearer",
  "issued_at": "1413424252525",
  "expires_in": "1424252525252",
  "refresh_token":"rVSmm3QaNa0xBVFbUISz1NZI15akvgLJ",
  "refresh_token_issued_at":"1467841035013",
  "refresh_token_expires_in":"14131213778771",
  "refresh_token_status": "Approved",
  "refresh_count":"0",
  "organization_name":"cerruti",
  "api_product_list":"[Product1, nhl_product]",
  "developer.email":"edward@slalom.org"
}

Summary of required policy elements

The following table describes JWT-specific elements used in the preceding examples:

Element Type Notes
Algorithm Static value Specifies the encryption algorithm to sign the token.
SecretKey Referenced value Provides the secret key used to verify or sign tokens with an HMAC algorithm: HS (256/384/512).
Private key Referenced value Provides the private key used to generate the token. Use only when the algorithm is one of RS (256/384/512).
Public key Referenced value Provides the public key used to verify the token. Use only when the algorithm is one of RS (256/384/512).

Unsupported policy elements

The following OAuthV2 policy elements are not supported with JWT token configurations:

Element Notes
ExternalAuthorization We do not support external authorization as the tokens be signed by Apigee and claims provided by Apigee either by default or through policy configuration.
ExternalAccessToken We do not support external tokens as the tokens be signed by Apigee and claims provided by Apigee either by default or through policy configuration.Note that we still support ExternalRefreshToken to honor any migration use cases.
RFCCompliantRequestResponse The generation and refresh of JWT access tokens is RFC compliant by default.

Usage notes

  • Signed JWTs are not supported.
  • In addition to a JWT access token, the policy response also includes an opaque refresh token for grant types where refresh tokens are supported. Only the password and auth code grant types support refresh tokens.
  • Include the Authorization header in requests sent to the proxy containing the OAuthV2 policy.
  • You cannot revoke a JWT access token. The generated JWT token will remain valid until it expires. Note, however, that you can revoke a refresh token, because refresh tokens are generated in the opaque string format. They are not JWTs.
  • Generation, verification, and refresh of access tokens must be handled by Apigee. Although an external application or gateway that has access to the public or secret key can decode the contents of the JWT, the external application does not have information about the API products that are identified by the client_id claim, and therefore cannot play a role in API proxy authorization.