The UMA Grant Flow

The UMA grant flow issues an RPT to the requesting party to allow access to a resource.

The implementation in AM covers the following scenarios:

  • The requesting party wants to perform an action over a resource (for example, downloading it), and the resource owner has already granted them that permission.

    During the UMA grant flow, AM issues the requesting party an RPT that they can present to the resource server to access the resource.

  • The requesting party wants to perform an action over a resource (for example, downloading it), and the resource owner has not granted them that permission.

    During the UMA grant flow, AM denies access to the resource, and sends the resource owner a request for permission on behalf of the requesting party.

    If the resource owner grants their permission (which happens asynchronously), the requesting party requests a new permission ticket and applies for another RPT.

The following diagram shows the first scenario:

UMA 2.0 Grant Flow Process
  • A requesting party, using a client application, requests access to an UMA-protected resource (labeled 1 and 2 in the diagram above).

  • The resource server checks the existing token (3) and determines that the requesting party does not have the correct privileges to access the resource. The resource server returns a permission ticket (4) to the client.

  • The client uses the permission ticket and a claim token to send an RPT from AM (5 and 6).

  • AM makes a policy decision using the requested scopes, the scopes permitted in the registered resource, and the user-created policy, and if successful returns an RPT (7 and 8).

  • The client presents the RPT to the resource server (9), which must verify the token is valid using the AM introspection endpoint (10). If the RPT is confirmed to be valid and non-expired (10), the resource server can return the protected resource to the client for access by the requesting party (11).

Perform the steps in the following procedures to issue an RPT to a requesting party, and have it rejected as in the second scenario. The resource owner will then grant permission over the resource, and the requesting party will retry the flow again:

To Acquire a PAT

This example assumes that a confidential client called UMA-Resource-Server is registered in AM with, at least, the following configuration:

  • Client Secret: password

  • Scopes: uma_protection

  • Grant Types: Resource Owner Password Credentials

    This example uses the Resource Owner Password Credentials grant, but you can use any grant type except the Client Credentials one to obtain the PAT.

The example also assumes that an identity for the resource owner,alice, exists in AM.

Perform the following steps to acquire a PAT on behalf of the resource owner>:

  • Create a POST request to the OAuth 2.0 access_token endpoint. The following example uses the Resource Owner Password Credentials grant:

    $ curl \
    --request POST \
    --data 'grant_type=password' \
    --data 'scope=uma_protection' \
    --data 'username=alice' \
    --data 'password=Ch4ng31t' \
    --data 'client_id=UMA-Resource-Server' \
    --data 'client_secret=password' \
    https://openam.example.com:8443/openam/oauth2/realms/root/access_token
    {
        "access_token": "057ad16f-7dba-4049-9f34-e609d230d43a",
        "refresh_token": "340f82a4-9aa9-471c-ac42-f0ca1809c82b",
        "scope": "uma_protection",
        "token_type": "Bearer",
        "expires_in": 4999
    }

    The value returned in access_token is the Protection API Token, or PAT Bearer token.

    Note

    To use the Resource Owner Password Credentials grant type, as described in RFC 6749, the default authentication chain in the relevant realm must allow authentication using only a username and password, for example by using a DataStore module. Attempting to use the Resource Owner Password Credentials grant type with a chain that requires any additional input returns an HTTP 500 Server Error message.

To Create a Permission Ticket

When the resource server receives a request for access to a resource, it contacts the authorization server to acquire a permission ticket. The permission ticket associates a request for a particular resource with the corresponding scopes. The PAT bearer token of the resource owner is used to map the request to the correct identity.

The permission ticket and the claim token are used to obtain an RPT. A new permission ticket must be used for each attempt to acquire an RPT.

This example assumes that a confidential client called UmaClient is registered in AM with, at least, the following configuration:

  • Client Secret: password

  • Scopes: openid, download

  • Grant Types: Resource Owner Password Credentials, UMA

    This example uses the Resource Owner Password Credentials grant, but you can use any grant type, except the Client Credentials one.

  • Token Endpoint Authentication Method: client secret post

    Confidential OpenID Connect clients can use several methods to authenticate, but this example uses client secret post for clarity. For more information, see OpenID Connect Client Authentication.

The example also assumes that an identity for the resource owner,bob, exists in AM.

  • Send a POST request to the UMA permission_request endpoint:

    $ curl -X POST \
    --header 'authorization: Bearer 057ad16f-7dba-4049-9f34-e609d230d43a' \ (1)
    --header 'cache-control: no-cache' \
    --header 'content-type: application/json' \
    --data '[
        {
            "resource_id" : "ef4d750e-3831-483b-b395-c6f059b5e15d0", (2)
            "resource_scopes" : ["download"]
        }
    ]' \
    https://openam.example.com:8443/openam/uma/realms/root/permission_request
    {
        "ticket": "eyJ0eXAiOiJ...XPeJi3E"
    }

    1

    Use the PAT Bearer Token previously acquired on behalf of the resource owner.

    2

    Specify the ID of the registered resource for which this permission ticket will maintain permission state information. See "To Register an UMA Resource (REST)".

    3

    The value returned in the ticket property is the permission ticket, which is used to obtain an RPT. See "To Obtain an RPT".

    Note

    The default lifetime for an UMA permission ticket is 120 seconds. Attempting to obtain a requesting party token after the permission ticket has expired will fail with an error message as follows:

    {
      "error_description": "The provided access grant is invalid, expired, or revoked.", "error": "invalid_grant"
    }

    You can alter the default lifetime of a permission ticket by going to Realms > Realm Name > Services > UMA Provider, and editing the Permission Ticket Lifetime (seconds) property.

To Gather Claims

The authorization server must gather claims from the requesting party to create a claim token.

  • Send a POST request to the OAuth 2.0 access_token endpoint. The value returned in the id_token property is the claim token required to obtain an RPT, along with the permission ticket acquired earlier:

    $ curl -X POST \
    --data 'client_id=UmaClient' \
    --data 'client_secret=password'
    --data 'grant_type=password' \
    --data 'scope=openid' \
    --data 'username=bob' \
    --data 'password=Ch4ng31t' \
    https://openam.example.com:8443/openam/oauth2/realms/root/access_token
    {
      "access_token": "f09f55e5-5e9c-48fe-aeaa-d377de88e8e6",
      "refresh_token": "ee2d35f6-5819-4734-8b3e-9af77a545563",
      "scope": "openid",
      "id_token": "eyJ0eXA...FBznEB5A",
      "token_type": "Bearer",
      "expires_in": 4999
    }

    1

    The value returned in the id_token property is the claim token, which is used to obtain an RPT. See "To Obtain an RPT".

    Note

    To use the Resource Owner Password Credentials grant type, as described in RFC 6749, the default authentication chain in the relevant realm must allow authentication using only a username and password, for example by using a DataStore module. Attempting to use the Resource Owner Password Credentials grant type with a chain that requires any additional input returns an HTTP 500 Server Error message.

To Obtain an RPT

The requesting party makes a request using the permission ticket and the claim token, in exchange for a RPT.

  1. Send a POST request to the OAuth 2.0 access_token endpoint. Make sure to include the permission ticket, ticket, and the claim_token. The following example results in an error description, indicating that "The client is not authorised to access the requested resource set." The authorization server sends a request to the resource owner to allow or deny access to the requesting party.

    $ curl -X POST \
    --data 'client_id=UmaClient' \
    --data 'client_secret=password' \
    --data 'grant_type=urn:ietf:params:oauth:grant-type:uma-ticket' \
    --data 'ticket=eyJ0eXAiOiJ...XPeJi3E' \  (1)
    --data 'claim_token=eyJ0eXA...FBznEB5A' \
    --data 'claim_token_format=http://openid.n(2)et/specs/openid-connect-core-1_0.html#IDToken' \
    https://openam.example.com:8443/openam/oauth2/realms/root/access_token
         {
      "ticket": "eyJ0eXAiOiJ...XPeJi3E",
      "error_description": "The client is not authorised to access the requested resource set. A request has been submitted to the resource owner requesting access to the resource",
      "error": "request_submitted"
    }

    1

    Specify the permission ticket acquired earlier. See "To Create a Permission Ticket".

    2

    Specify the claim token acquired earlier. See "To Gather Claims".

    Note

    The default lifetime for an UMA permission ticket is 120 seconds. Attempting to obtain a requesting party token after the permission ticket has expired will fail with an error message as follows:

    {
      "error_description": "The provided access grant is invalid, expired, or revoked.", "error": "invalid_grant"
    }

    If the ticket has expired, obtain another by repeating the steps in "To Create a Permission Ticket".

    You can alter the default lifetime of a permission ticket by navigating to Realms > Realm Name > Services > UMA Provider, and editing the Permission Ticket Lifetime (seconds) property.

  2. The resource owner, Alice, logs into AM to view the access request. Alice clicks Shares > Requests, and clicks Allow to grant download access to Bob, the requesting party.

    Consent Screen Presented to the Resource Owner
    The consent screen presented to the resource owner.

  3. Because each permission token can only be used once, request a new permission token by performing the steps in "To Create a Permission Ticket".

  4. Resubmit the previous POST request for the RPT, with the new permission ticket obtained in the previous step and the original claim token:

    curl -X POST \
    --data 'client_id=UmaClient' \
    --data 'client_secret=password' \
    --data 'grant_type=urn:ietf:params:oauth:grant-type:uma-ticket' \
    --data 'ticket=eyJ0efBiOiJ...XPeJc2A' \  (1)
    --data 'claim_token=eyJ0eXA...FBznEB5A' \
    --data 'claim_token_format=http://openid.n(2)et/specs/openid-connect-core-1_0.html#IDToken' \
    https://openam.example.com:8443/openam/oauth2/realms/root/access_token
         {
        "access_token": "Aw4a92ZoKsjadWKw2d4Rmcjv7DM",
        "token_type": "Bearer",
        "expires_in": 3599
    }

    1

    Specify a refreshed permission ticket acquired earlier, otherwise you will receive a response such as: The provided access grant is invalid, expired, or revoked. See "To Create a Permission Ticket".

    2

    Specify the same claim token as the first request for an RPT.

    The access_token is the RPT, which lets the requesting party access the resource through a client.

  5. (Optional) You can use the /oauth2/introspect endpoint to inspect the properties of the RPT. Use the PAT issued to the resource owner for authenticating to the authorization server, and specify the RPT token in a query parameter named token, as follows:

    $ curl --header 'authorization: Bearer 057ad16f-7dba-4049-9f34-e609d230d43a' \
    'https://openam.example.com:8443/openam/oauth2/realms/root/introspect?token=Aw4a92ZoKsjadWKw2d4Rmcjv7DM'
        {
        "active": true,
        "permissions": [
            {
                "resource_id": "ef4d750e-3831-483b-b395-c6f059b5e15d0",
                "resource_scopes": [
                    "download"
                ],
                "exp": 1522334692
            }
        ],
        "token_type": "access_token",
        "exp": 1522334692,
        "iss": "https://openam.example.com:8443/openam/oauth2"
    }
Read a different version of :