Show / Hide Table of Contents

    OAuth 2.0 Token Exchange

    The Token Exchange extension specifies a process by which a client can acquire its own tokens using a different set of tokens. This has several applications, including:

    • Single-sign-on between multiple mobile apps without launching a web browser
    • A resource server exchanging a client's tokens for its own tokens

    In alignment with the specification outlined in RFC 8693, Identify supports this feature, underscoring our commitment to providing robust authentication and authorization mechanisms for our users and clients.

    What is Token Exchange?

    OAuth 2.0 Token Exchange extends the capabilities of the OAuth 2.0 protocol by allowing client applications to seamlessly request and acquire security tokens, such as access tokens, from an authorization server functioning as a Security Token Service (STS).

    Put simply, a client application can request access to resources using an access token obtained from a third-party authorization server. It can then exchange this token for an access token issued by the target authorization server. The client then uses this exchanged token to authenticate its request for target resources.

    Security tokens obtained from the Identify can allow the bearer to:

    • Impersonate the original service

    oauth2-token-exchange-impersonation-diagram-happy-case

    • Delegate permissions from the original service

    oauth2-token-exchange-delegation-diagram-happy-case

    OpenId Connect Discovery endpoint

    The OpenID Connect Discovery endpoint now contains a new supported grant type: urn:ietf:params:oauth:grant-type:token-exchange in the grant_types_supported property:

      "grant_types_supported": [
        ...
        "urn:ietf:params:oauth:grant-type:token-exchange"
      ],
    

    Configuration

    To use the Token exchange grant type in Identify, follow these steps to configure the OAuth/OIDC applcation:

    1. Open the existing OAuth/OIDC application in the application list.
    2. Go to its Security tab and enable the Allow Token Exchange setting.

    Allow token exchange

    1. Validate tokens from trusted issuers: The Token Exchange grant type supports security tokens signed by RSA or HMAC keys. To validate tokens from trusted issuers, depending on the signing algorithm, you can add them to the trusted issuers in the Bootstrap token trusted issuers section or the Issuer symmetric signing keys section in its Connection tab.

    You can also enable additional validation option:

    • Signing certificate revocation check: When the selected value is not None, Identify performs a revocation check for the signing certificate used to sign the security token in the subject_token parameter and the actor_token parameter (if present).

    As a side note, if the security token provided in either the subject_token parameter or the actor_token parameter is also issued by your Safewhere Identify instance and is signed using its primary signing certificate, you do not need to add its issuer information to the trusted issuer list in the Bootstrap token trusted issuers section.

    Token exchange request

    Perform a POST operation to the token endpoint:

    https://#identifydomain/runtime/oauth2/token.idp
    

    With the following parameters:

    Parameter Requirement type Description
    grant_type REQUIRED This must be "urn:ietf:params:oauth:grant-type:token-exchange"
    subject_token REQUIRED Indicates the security token that represents the identity of the party on behalf of whom the request is being made
    subject_token_type REQUIRED Indicates the type of the security token in the "subject_token" parameter:
    - urn:ietf:params:oauth:token-type:access_token
    - urn:ietf:params:oauth:token-type:refresh_token
    - urn:ietf:params:oauth:token-type:id_token
    - urn:ietf:params:oauth:token-type:jwt
    actor_token OPTIONAL Indicates the security token that represents the identity of the acting party
    actor_token_type REQUIRED* Indicates the type of the security token in the "actor_token" parameter:
    - urn:ietf:params:oauth:token-type:access_token
    - urn:ietf:params:oauth:token-type:refresh_token
    - urn:ietf:params:oauth:token-type:id_token
    - urn:ietf:params:oauth:token-type:jwt
    (*) When the "actor_token" request parameter is given, this parameter is REQUIRED
    requested_token_type OPTIONAL Indicates the type of the requested security token:
    - urn:ietf:params:oauth:token-type:access_token
    - urn:ietf:params:oauth:token-type:refresh_token
    - urn:ietf:params:oauth:token-type:id_token
    - urn:ietf:params:oauth:token-type:jwt
    If omitted, the requested security token type is "urn:ietf:params:oauth:token-type:access_token"
    resource OPTIONAL Indicates the target service or resource where the client intends to use the requested security token. This parameter may be specified multi times in the token request
    scope OPTIONAL A list of space-delimited registered scopes
    client_id REQUIRED Your application's client ID
    client_secret REQUIRED* Your application's client secret.
    (*) When the client authentication method is either client_secret_basic or client_secret_post, this parameter is REQUIRED

    Impersonation token exchange request sample

    In the following token exchange request, a client is requesting a token and providing only a subject_token.

    POST /runtime/oauth2/token.idp  //Line breaks for clarity
    Host: identify01.identify.safewhere.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
    &subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
    &subject_token=eyJhbGc...jZ7vg67LHQ
    &client_id=rfc8693-test
    &client_secret=rfc8693-secret
    

    Delegation token exchange request sample

    In the following token exchange request, a client is requesting a token and providing both a subject_token and an actor_token.

    POST /runtime/oauth2/token.idp  //Line breaks for clarity
    Host: identify01.identify.safewhere.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
    &scope=openid
    &subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
    &subject_token=eyJhbG...DFf3-8Z4
    &client_id=oidc-rfc8693-test
    &client_secret=rfc8693-secret
    &actor_token=eyJhbGciOi...jjfYvw
    &actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
    

    "may_act" claim validation

    The may_act claim in the security token provided provided in the subject_token is used to ascertain if the client (or party identified in the actor_token) is authorized to engage in the requested delegation or impersonation. Its claim value is a JSON object, and members in the JSON object are claims that identify the party that is asserted as being eligible to act for the party identified by the JWT containing the claim.

    Example:

        "may_act": {
            "sub": "test_identify01",
            "client_id": "identify01_subjectClientID"
        }
    

    Identify will validate this may_act claim according to the ActAs authorization claim rules configured in the OAuth/OIDC application

    actas-authorization-claim-rules

    Here are the validation rules:

    • If the ActAs authorization claim rules are not set (the list is empty), any request containing a may_act claim will be rejected.
    • If there are configured values in the ActAs authorization claim rules but the may_act claim is missing, the request will also be rejected.
    • If both the may_act claim and ActAs authorization claim rules are present, Identify will verify that all claims within may_act match at least one of the rules. A request is deemed valid only if every claim in may_act is fulfilled. Note that the values in ActAs authorization claim rules can include regular expressions.

    When a valid may_act claim is present, it will be applied to the generating act claim in the issued access token.

    Token Exchange response

    Successful response

    If the token request is valid and meets all policies and criteria, Identify generates a fresh security token with the following capabilities:

    • It allows the requester to assume the identity of another entity if no actor token was provided in the request.
    • If an actor token was provided and the requester's identity is confirmed, it enables the requester to delegate third-party privileges.

    The following table shows parameters related to the token exchange response:

    Parameter Description
    token_type Its value is "Bearer"
    access_token Indicates the issued security token in response to the token exchange request
    expires_in Indicates the validity lifetime of the issued security token, in seconds
    issued_token_type Indicates the token type of the issued security token in response to the requested_token_type parameter in the token exchange request

    An example:

    token_ex_response

    Dependent on the requested_token_type, the response may contain an additional id_token or refresh_token.

    id_token_in_response

    Access token parameter content

    The access token contains an act claim, which includes the identity information of the subject token:

    "act": {
        "sub": "usersubject",
        "client_id": "webmvc_codeflow_id_oidc01"
    }
    

    If the token request contains a valid actor_token that includes the act claim, the issued act claim in the response access token will be nested.

    "act": {
        "sub": "useractor",
        "client_id": "webmvc_codeflow_id_oidc02",
        "act": {
            "sub": "fromactortoken",
            "client_id": "fromactortoken__ClientID"
        }
    }
    

    You can learn more about impersonation token requests or delegation token requests here

    Actor claim for Token Introspection

    When invoking the Introspection endpoint to inspect the access token mentioned above, the Introspection response contains the act (actor) claim. Its value has the same semantics and format as the claim of the same name in the access token.

    Example:

    {
        ...
        "act": {
            "sub": "useractor",
            "client_id": "webmvc_codeflow_id_oidc02",
            "act": {
                "sub": "fromactortoken",
                "client_id": "fromactortoken__ClientID"
            }
        },
        ...
    }
    

    Error response

    If the token request itself is not valid, or if either the subject_token or the actor_token is invalid for any reason, Identify will return an error response with the error parameter value set to invalid_request

    {
        "error": "invalid_request",
        "error_description": "..."
    }
    
    Back to top Generated by DocFX