Show / Hide Table of Contents

    Client credentials flow for OpenId Connect and OAuth 2.0

    Overview

    The Client Credentials Flow, defined in RFC 6749, section 4.4, allows non-interactive clients (such as CLIs, daemons, or backend services) to directly request an access_token from Identify using their client credentials (client ID and client secret) for authentication. In this scenario, the access_token represents the non-interactive client itself, not an end user.

    oauth2-token-client-credential-flow-happy-case

    How to implement the Client Credentials grant

    The client's grant type property is set appropriately

    The grant_type property must be set to client_credentials

    Register the OAuth20/OIDC application in Identify

    From the Safewhere Admin applications list, you can create an OAuth 2.0 application, then open its subtabs and update the following:

    • On its connection tab:
      • Client ID: Specifies the unique ID of the application. Client ID is case-sensitive.
      • Client secret: Specifies the Client secret of the application. Client secret is case-sensitive.
      • Token endpoint authentication method: Specifies the client authentication method to the token endpoint.
      • Allowed Callback URIs: Specifies the redirect URL after successful authentication, e.g https://identifydomain/runtime/
      • Application name: Specifies the name of the application
      • Security token audiences: Specifies the recipients (usually in URI format) that issued access tokens are intended for. When the resource parameter is missing, an access token is issued with its 'aud' claim set to all configured audiences.

    swadmin-oauth2-client-credential-connection

    • On its security tab:
      • JWS algorithm: Either RSASigning or HMACSymmetric.
      • Symmetric signing key: Used to generate a HMAC Symmetric signing key; key can be 32-byte, 48-byte, or 64-byte. You can then either copy the key and paste it to the configuration or check the appropriate check box and click Select key to apply it.
      • Allow client credentials flow: This setting must be True.

    swadmin-oauth2-client-credential-security

    • Security tab:

      • JWS algorithm: either RSASigning or HMACSymmetric.
      • Symmetric signing key: used to generate a HMAC Symmetric signing key; key can be 32-byte, 48-byte, or 64-byte. You can then either copy the key and paste it to the configuration or check the appropriate check box and click Select key to apply it.
      • Allow client credentials flow: this setting must be True.

    swadmin-oauth2-client-credential-security

    Ask for a token

    To ask Identify for tokens for any of your authorized client applications, perform a POST operation to the token endpoint:

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

    URI parameters:

    Parameter Description
    client_id Your application's client ID
    client_secret Your application's client secret
    grant_type This must be "client_credentials"

    Here is sample:

    setting

    Successful response

    If the token request is valid and meets all policies and criteria, Identify responds a signed JSON Web Token, the token's type (which is Bearer), and in how much time it expires in Unix time (3600 seconds, which means 1 hour).

    {
        "token_type": "Bearer",
        "access_token": "eyJhbGciOiJS...L9yrfg",
        "expires_in": 3600
    }
    

    If you decode the access_token, you will see that it contains the following claims:

    {
        "urn:identify:rest-api:role": "Administrator",
        "sub": "oauth2_codeflow,
        "name": "oauth2_codeflow_restapi_token_336c7c49-0122-e51c-a851-28756b1020dd",
        "client_id": "oauth2_codeflow_restapi_token_336c7c49-0122-e51c-a851-28756b1020dd",
        "token_usage": "access_token",
        "jti": "d87ac51d-8aad-4146-b79a-ab80a85107d5",
        "scope": "identify*scim",
        "aud": "https://identify01.identify.safewhere.com/runtime/",
        "azp": "oauth2_codeflow_restapi_token_336c7c49-0122-e51c-a851-28756b1020dd",
        "iat": 1735372095,
        "nbf": 1735372095,
        "exp": 1735375695,
        "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    

    Tip: to decode a signed JSON Web Token you can use any JSON Web Token decoder tool such as https://www.rcfed.com/OAuth/JWTTokenDecode. Beware that some websites send your data to their servers though.

    Error response

    If the token request is not valid, Identify responds with an error response to the client.

    {
        "error": "invalid_request",
        "error_description": "..."
    }
    

    Claim Transformation Support

    Claim Transformations are steps in the claim pipeline that transform the claim set attached to a token. The way in which this transformation is done depends on the type of Claim Transformation object. You can set up claim pipeline transformation rules that can be attached to any of your authorized client applications.

    Given that you have a JWT token like below:

    {
      "sub": "client_connect_sample_id",
      "name": "client_connect_sample_id",
      "token_usage": "access_token",
      "jti": "3696a10d-1df4-4baf-98db-6003889790a9",
      "scope": "identify*empty",
      "aud": "https://idpmaster60.safewhere.local/runtime",
      "azp": "client_connect_sample_id",
      "iat": 1590370394,
      "nbf": 1590370394,
      "exp": 1590373994,
      "iss": "https://idpmaster60.safewhere.local/runtime/oauth2"
    }
    

    Because the Client credentials flow has no user context, only certain claims transformations can be used.

    Add Value claim transformation

    You can set up an Add Value claim transformation.

    add-value-claim-transformation-configuration

    Then attach the Add Value claim transformation to your OAuth 2.0 application.

    add-value-claim-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
      "sub": "client_connect_sample_id",
      "role": [
        "ClaimAdmin",
        "ConnectionAdmin",
        "Identify Service",
        "UserAdmin"
      ],
      "urn:identify:rest-api:role": "Observer",
      "company": "Safewhere",
      "Title": "Developer",
      "name": "client_connect_sample_id",
      "token_usage": "access_token",
      "jti": "3696a10d-1df4-4baf-98db-6003889790a9",
      "scope": "identify*empty",
      "aud": "https://idpmaster60.safewhere.local/runtime",
      "azp": "client_connect_sample_id",
      "iat": 1590370394,
      "nbf": 1590370394,
      "exp": 1590373994,
      "iss": "https://idpmaster60.safewhere.local/runtime/oauth2"
    }
    

    Scripting claim transformation

    Set up a Scripting claim transformation.

    scripting-claim-transformation-application-configuration

    Attach the Scripting claim transformation to your OAuth 2.0 application.

    scripting-claim-transformation-configuration

    Finally, send a request to get an access_token and check its content:

    {
      "Country": "Denmark",
      "sub": "client_connect_sample_id",
      "role": [
        "ConnectionAdmin",
        "Identify Service",
        "UserAdmin"
      ],
      "company": "Safewhere",
      "Title": "Developer",
      "name": "client_connect_sample_id",
      "token_usage": "access_token",
      "jti": "3696a10d-1df4-4baf-98db-6003889790a9",
      "scope": "identify*empty",
      "aud": "https://idpmaster60.safewhere.local/runtime",
      "azp": "client_connect_sample_id",
      "iat": 1590370394,
      "nbf": 1590370394,
      "exp": 1590373994,
      "iss": "https://idpmaster60.safewhere.local/runtime/oauth2"
    }
    

    Mapping claim transformation

    Before trying out the Mapping claim transformation, you can use the "Add Value" claim transformation to add some claim values first.

    mapping-claim-transformation-configuration

    Set up a Mapping claim transformation.

    mapping-claim-transformation-configuration

    Attach the Mapping claim transformation to your OAuth 2.0 application.

    mapping-claim-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
     "sub": "client id _ WeXKAjwbb0s=",
     "role": [
      "ClaimAdmin",
      "ConnectionAdmin",
      "Identify Service",
      "UserAdmin"
     ],
     "Title": "Developer",
     "company": "Safewhere VN",
     "name": "client id _ WeXKAjwbb0s=",
     "token_usage": "access_token",
     "jti": "da7a00d5-d468-4923-a54b-e0b942b806c3",
     "scope": "identify*empty",
     "aud": "https://identify01.identify.safewhere.com/runtime/",
     "azp": "client id _ WeXKAjwbb0s=",
     "iat": 1597822711,
     "nbf": 1597822711,
     "exp": 1597826343,
     "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    

    Claim Filter claim transformation

    Set up a Claim Filter claim transformation.

    claim-filter-transformation-configuration

    Attach the Claim Filter claim transformation to your OAuth 2.0 application.

    claim-filter-claim-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
     "role": [
      "ConnectionAdmin",
      "UserAdmin"
     ],
     "Title": "Developer",
     "sub": "client id _ WeXKAjwbb0s=",
     "name": "client id _ WeXKAjwbb0s=",
     "token_usage": "access_token",
     "jti": "efd4b367-225c-42d9-abe4-e7d679272a77",
     "scope": "identify*empty",
     "aud": "https://identify01.identify.safewhere.com/runtime/",
     "azp": "client id _ WeXKAjwbb0s=",
     "iat": 1597825517,
     "nbf": 1597825517,
     "exp": 1597829117,
     "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    

    External Claims claim transformation

    Set up an External Claims claim transformation.

    external-claims-transformation-configuration

    Attach the External Claims claim transformation to your OAuth 2.0 application.

    external-claim-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
     "automation_test": "login-logout-automation-test",
     "sub": "client id _ WeXKAjwbb0s=",
     "role": [
      "ClaimAdmin",
      "ConnectionAdmin",
      "UserAdmin",
      "Identify Service"
     ],
     "urn:identify:rest-api:role": "Observer",
     "company": "Safewhere",
     "Title": "Developer",
     "name": "client id _ WeXKAjwbb0s=",
     "token_usage": "access_token",
     "jti": "a2c5ff8a-99fd-4361-8423-b5dd6382f7d8",
     "scope": "identify*empty",
     "aud": "https://identify01.identify.safewhere.com/runtime/",
     "azp": "client id _ WeXKAjwbb0s=",
     "iat": 1597826289,
     "nbf": 1597826289,
     "exp": 1597829904,
     "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    

    Remove Duplicate claim transformation

    Before trying out the Remove Duplicate claim transformation, you can add some duplicate values to a claim type (e.g: "title") by using the "Add Value" claim transformation

    remove-duplicate-claim-transformation-configuration

    Set up a Remove Duplicate claim transformation.

    remove-duplicate-claims-transformation-configuration-1

    Attach the Remove Duplicate claim transformation to your OAuth 2.0 application.

    remove-duplicate-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
     "sub": "client id _ WeXKAjwbb0s=",
     "role": [
      "ClaimAdmin",
      "ConnectionAdmin",
      "UserAdmin",
      "Identify Service"
     ],
     "urn:identify:rest-api:role": "Observer",
     "company": "Safewhere",
     "title": "Developer",
     "name": "client id _ WeXKAjwbb0s=",
     "token_usage": "access_token",
     "jti": "62a99deb-29e2-46b9-8751-b68c277bd80b",
     "scope": "identify*empty",
     "aud": "https://identify01.identify.safewhere.com/runtime/",
     "azp": "client id _ WeXKAjwbb0s=",
     "iat": 1597830342,
     "nbf": 1597830342,
     "exp": 1597833942,
     "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    

    Exclude Identify Claims claim transformation

    Set up an Exclude Identify Claims claim transformation.

    exclude-claims-transformation-configuration

    Attach the Exclude Identify Claims claim transformation to your OAuth 2.0 application.

    exclude-claim-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
     "role": [
      "ClaimAdmin",
      "UserAdmin",
      "Identify Service"
     ],
     "company": "Safewhere",
     "sub": "client id _ WeXKAjwbb0s=",
     "name": "client id _ WeXKAjwbb0s=",
     "token_usage": "access_token",
     "jti": "b60cbcf2-4cdc-4dee-81be-0f77c0cfc48f",
     "scope": "identify*empty",
     "aud": "https://identify01.identify.safewhere.com/runtime/",
     "azp": "client id _ WeXKAjwbb0s=",
     "iat": 1597831669,
     "nbf": 1597831669,
     "exp": 1597835281,
     "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    

    "Exclude Passthrough Claims" claim transformation

    Set up an Exclude Passthrough Claims claim transformation.

    exclude-passthrough-transformation-configuration

    Attach the Exclude Passthrough Claims claim transformation to your OAuth 2.0 application.

    exclude-passthrough-transformation-application-configuration

    Finally, send a request to get an access_token and check its content:

    {
     "role": [
      "ConnectionAdmin",
      "UserAdmin"
     ],
     "sub": "client id _ WeXKAjwbb0s=",
     "name": "client id _ WeXKAjwbb0s=",
     "token_usage": "access_token",
     "jti": "dd484ea8-734f-4ecd-bf4e-503a563b6af3",
     "scope": "identify*empty",
     "aud": "https://identify01.identify.safewhere.com/runtime/",
     "azp": "client id _ WeXKAjwbb0s=",
     "iat": 1597832154,
     "nbf": 1597832154,
     "exp": 1597835764,
     "iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
    }
    
    Back to top Generated by DocFX