Access Management 7.2.2

JWT profile for OAuth 2.0 authorization grant

The JWT profile for OAuth 2.0 authorization grant is designed for environments that want to use the REST-based services provided by AM’s OAuth 2.0 framework, but keep their existing authentication services. The trust relationship must be able to be expressed with a JWT bearer token.

Because the trust relationship is already established, this flow does not require the end user’s interaction.

RFC 7523 defines the use of JWT bearer tokens for requesting access tokens and for client authentication.

Read this section for information about requesting access tokens.

To use JWTs for client authentication, refer to Authenticate clients with JWT profiles.

As the authorization server, AM must validate the bearer JWT to issue the access token to the client. To ensure that malicious clients cannot self-sign their own JWTs to acquire tokens, AM requires the token issuer to be pre-registered as a special type of agent.

JWT Bearer Profile for Authorization Grant
Figure 1. JWT Bearer Profile for Authorization Grant
  1. The client requests a JWT from the issuer. The client itself can be the issuer, in which case it will create a JWT for itself before starting the OAuth 2.0 flow.

    Regardless of who signs the JWT, the issuer must be pre-registered in AM as a trusted JWT issuer. For more information, refer to Configure a trusted JWT issuer agent.

  2. The issuer returns a signed JWT to the client; JWTs with message authentication codes (MACs) applied to them are not supported.

    The JWT must contain, at least, the following claims in the payload:

    • aud. Specifies a string or an array of strings that is the intended audience of the JWT. Must be set to, or contain, the authorization server’s token endpoint.

    • exp. Specifies the expiration time of the JWT in Unix time.

      Providing a JWT with an expiry time greater than 30 minutes causes AM to return a JWT expiration time is unreasonable error message.

    • iss. Specifies the unique identifier of the JWT issuer. This could be the client or a third party.

      The identifier must match the issuer field configured in the trusted JWT issuer agent.

    • sub. Specifies the principal who is the subject of the JWT. It must be a string that identifies the resource owner.

      You can configure the trusted JWT issuer agent to check a different claim for the principal. For example, the preferred_username from an ID token.

      In this case, the JWT would contain both the sub and the preferred_username claims.

      For more information, refer to Configure a trusted JWT issuer agent.

      The following is an example of the payload of a basic JWT:

      {
        "aud": [
          "https://openam.example.com:8443/openam/oauth2/realms/realms/alpha/root/access_token"
        ],
        "iss": "https://www.example.com/issuer",
        "exp": 1555530663,
        "sub": "demo"
      }

      For an example of a JWT containing different claims as supported by the trusted JWT issuer agent, refer to Configure a trusted JWT issuer agent.

      For more information about JWTs, refer to the RFC 7523 standard.

  3. The client includes the JWT and a client assertion type in the call to the OAuth 2.0 endpoint in the following parameters:

    • grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer

    • assertion=my-JWT

    For example:

    $ curl \
    --request POST \
    --data "client_id=myClient" \
    --data "client_secret=forgerock" \
    --data "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer" \
    --data "assertion=eyAiYWxnIjogIlJTMjU2IiB9.eyAic3ViIjogImp3…​"
    --data "redirect_uri=http://www.example.com" \
    --data "scope=write" \
    "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/access_token"

    For information about the parameters supported by the /oauth2/access_token endpoint, refer to /oauth2/access_token.

    For information about client authentication methods, refer to OAuth 2.0 client authentication.

  4. AM validates the JWT following the guidance specified in section 3 of the RFC7523 and also performs the following additional checks:

    1. Decodes the payload and compares the value of the iss claim with the value of the JWT Issuer field in the list of trusted JWT issuer agents.

    2. Validates the JWT signature either with the keys exposed on the trusted issue agent’s JWK URI, or with the keys configured in the JWK Set field of the agent.

    If AM cannot validate the JWT it will return an error, such as JWT signature is invalid.

  5. The authorization server issues an access token to the client.

  6. The client requests access to the protected resources from the resource server.

  7. The resource server contacts the authorization server to validate the access token.

  8. The authorization server validates the token and responds to the resource server.

  9. If the token is valid, the resource server allows the client to access the protected resources.

Configure a trusted JWT issuer agent

Perform the steps in this procedure to configure a trusted JWT issuer agent:

  1. In the AM admin UI, go to Realms > Realm Name > Applications > OAuth 2.0 > Trusted JWT Issuer.

  2. Add a new trusted JWT issuer agent.

  3. Complete the following fields to create the agent:

    • In the Agent ID field, give the trusted JWT issuer agent a name.

      For example, myJWTAgent.

    • In the JWT Issuer field, provide the URI of the JWT issuer.

      This URI must match the value of the issuer (the iss claim) in the JWTs.

    • Select Create.

      You are presented with a screen with additional information regarding the agent.

  4. Review the trusted JWT issuer agent information.

    You must, configure either the JWKs URI or the JWK Set fields, as follows:

    • JWKs URI: specifies a URI in the JWT issuer that exposes the verification keys that AM will use to validate the JWT signature. For example, http://www.example.com/issuer/jwk_uri.

      If you configure this field, ensure the following properties are configured with sensible values for your environment:

      • JWKs URI content cache timeout in ms

      • JWKs URI content cache miss cache time

    • JWK set: Specifies a JWK set containing the verification keys to validate the JWT signature.

      The following is an example of an elliptic curve JWK set:

      {
        "keys": [{
           "kty": "EC",
           "crv": "P-256",
           "x": "i-rdOmi5lC3pn3y5sTgYiLLFVFY7XxDLinWneHEaAXA",
           "y": "mxmqqauiq44INgyyPP2vATt3IkDL_6W5CAcfAMSZl8k",
           "kid": "signing_key",
           "x5c": [
               "MIIBSjCB76ADAgEC.....955PByPrflZkQOC/g==" ]
        }]
      }

      For more information about the contents of the JWK set, refer to the JSON Web Key (JWK) specification.

    You can store more than one key in the JWK set. However, it is easier to implement key rotation exposing the validation keys on the URI instead.

  5. Configure the following values to suit your environment:

    • Consented Scopes Claim. The name of a JWT claim that indicates which scopes the resource owner consented to. The claim in the JWT can contain either a JSON array or a space-separated allowlist of scopes that the resource owner has consented to.

      For example, if you configure the scp claim name in this field and the JWT contains the claim "scp":"read", but you request both the read and write scopes, AM will only grant the read scope.

      Leave this field blank to allow any scope.

      The following are example JWTs containing a claim that specifies scopes:

      {
         "aud": [
             "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/access_token"
         ],
         "iss": "https://www.example.com/issuer",
         "exp": 1555530663,
         "sub": "demo",
         "scope": ["read", "write"]
      }

      In this case, the scope claim is a JSON array of scopes.

      {
         "aud": [
             "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/access_token"
         ],
         "iss": "https://www.example.com/issuer",
         "exp": 1555530663,
         "sub": "demo",
         "scp": "read write"
      }

      In this case, the scp claim is a space-separated list of scopes.

    • Resource Owner Identity Claim. Claim in the JWT that identifies the resource owner in AM. By default, the sub claim.

      Note that even if you configure the trusted JWT issuer agent to verify a different claim, such as the preferred_username claim, the sub claim must still exist in the JWT.

    • Allowed Subjects. List of subjects this JWT issuer is allowed to provide consent for.

      For example, if you configure the demo user in this field but the JWT subject value is demo2, AM will not grant the access token.

      Leave it blank to provide consent to any user.

  6. Save your changes.

    The trusted JWT issuer agent is ready for use.