PingOne Advanced Identity Cloud

JWT profile for authorization

RFC 7523 JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants defines the use of JWT bearer tokens for requesting access tokens and for client authentication. This page describes how to exchange a JWT bearer token for an access token. For client authentication, refer to JWT profile.

In this profile, the client or another issuer authenticates the resource owner, obtains authorization, and prepares a signed JWT bearer token to use the PingOne Advanced Identity Cloud REST APIs. PingOne Advanced Identity Cloud does not interact with the resource owner in this grant flow.

You configure PingOne Advanced Identity Cloud to trust the issuer with a trusted JWT issuer profile to access the issuer’s public keys. PingOne Advanced Identity Cloud supports only asymmetric (public-private key) signing algorithms; HMAC-based signing is not supported. PingOne Advanced Identity Cloud validates the JWT signature and content using the trusted JWT issuer profile.

JWT for authorization flow

oauth2-jwt-bearer-authz
  1. The client directs the resource owner to the issuer for authentication and to obtain authorization.

  2. The issuer authenticates the resource owner and obtains consent.

  3. On success, the issuer supplies a signed JWT.

  4. The issuer redirects the resource owner to the client with the JWT.

  5. The client exchanges the JWT for an access token.

  6. PingOne Advanced Identity Cloud validates the JWT according to RFC 7523, section 3 with the following additional checks:

    • Match the iss claim with the trusted JWT issuer JWT Issuer setting.

    • Validate the JWT signature with the trusted JWT issuer’s public key.

    PingOne Advanced Identity Cloud returns an error if it cannot validate the JWT.

  7. As authorization server, PingOne Advanced Identity Cloud issues an access token to the client.

  8. The client uses the token when requesting access to protected resources.

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

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

  11. The resource server allows the client to access the protected resources.

Demonstrate JWT for authorization flow

Set up a trusted JWT issuer profile

  1. Under Native Consoles > Access Management, go to Realms > Realm Name > Applications > OAuth 2.0 > Trusted JWT Issuer.

  2. Click + Add Trusted JWT Issuer Agent, provide the following settings, and then click Create:

    Agent ID

    An identifier for the profile.

    JWT Issuer

    The URI to uniquely identify the issuer; this must match the iss claim in the JWT.

  3. Configure at least the issuer’s public keys by setting either of these fields:

    JWKs URI

    The URL to the issuer’s JSON Web Key (JWK) set; for example: https://www.example.com/issuer/jwk_uri. Use this setting to simplify the process of key rotation.

    If you configure this field, also check and update the JWKs URI content cache timeout in ms and JWKs URI content cache miss cache time as necessary.

    JWK Set

    The issuer’s JWK set; for example:

    {
      "keys": [{
        "kty": "RSA",
        "e": "AQAB",
        "kid": "example",
        "alg": "RS256",
        "n": "uzfshBc3malq8JYIyskEKV6e0X42oAboChGEMKCld92YRsVpiPWc4LpFw2lFhOGy6v5qxnkEsLJf-aMQNSMFkux0356PBGWWWJO1_IlC6EjMJMMvKaCjzZLpEVXEtKj0VjXZl07kQQ8F8SGc_tzp6Sgd-R3nR-tC1HpVAar_DFhISikwm1NyupEhI05sxhyiC_09f5xwY23wwpXx4qrGETsogP8k4FE9jgCiyhafhj9qMHI6skGoLyQgQkqFRn5Krfg6UdPvnEwF5sK3GATWk7sUKR62-ia_986Em0ObSP5230WS8hJO__o3MN-b6qN3o-mdO-a1_E1PRLRY03GHHQ"
      }]
    }
  4. Configure additional settings as necessary:

    Consented Scopes Claim

    A JWT claim specifying an array or space-separated allowlist of scopes.

    Resource Owner Identity Claim

    The JWT claim holding the PingOne Advanced Identity Cloud identifier for the resource owner.

    When you configure an alternative identifier, the JWT must still include a sub claim.

    Allowed Subjects

    Optionally restrict the subjects to the resource owners specified here.

  5. Save your changes.

Set up an OAuth 2.0 client

  1. Create an application owner profile and record the username and password.

  2. Register a client application.

    1. In the Advanced Identity Cloud admin UI, go to Applications and select + Custom Application.

    2. Select the sign-in method as OIDC - OpenId Connect and application type as Web.

    3. Create the application, providing the following details:

      Name

      myClient

      Owners

      <application-owner>

      Client ID

      myClient

      Client Secret

      forgerock

    4. Switch to the Sign On tab and under General Settings, set these fields to have the following values:

      Sign-in URLs

      https://www.example.com:443/callback

      Grant Types

      Add JWT Bearer

    5. Save your changes.

Set up a resource owner profile

  1. Create a resource owner profile.

  2. Record the identifier of the profile to use as the sub claim in the JWT.

Issue a signed JWT

As the issuer, prepare and sign the JWT for the client.

The JWT is signed using the issuer’s asymmetric key pair and includes at least the following claims:

Claim Description

aud

A string or array of strings for the intended audience(s), the PingOne Advanced Identity Cloud access token endpoint(s).

Example: "aud": "https://<tenant-env-fqdn>:443/am/oauth2/realms/root/realms/alpha/access_token"

Notice the port number in the URL.

exp

Expiration time in seconds since Jan 1, 1970, UTC.

Example: "exp": 1680855108

iss

The JWT issuer’s unique identifier.

Example: "iss": "https://www.example.com/issuer"

sub

The PingOne Advanced Identity Cloud identifier for the resource owner.

Example: "sub": "a0325ea4-9d9b-4056-931b-ab64704cc3da"

Request an access token

As the client, exchange the JWT for an access token:

$ curl \
--request POST \
--user 'myClient:forgerock' \
--data 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer' \
--data 'assertion=<jwt-from-issuer>' \
--data 'redirect_uri=https://www.example.com:443/callback' \
--data 'scope=openid' \
'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token'
{
  "access_token": "<access-token>",
  "refresh_token": "<refresh-token>",
  "scope": "openid",
  "id_token": "<id-token>",
  "token_type": "Bearer",
  "expires_in": 3599
}

As shown in the example, the request includes these parameters:

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer

Required for this grant.

assertion=<jwt-from-issuer>

The signed JWT.

scope=openid

Required if the scopes are not in the JWT and no default scopes are set for the client.