Token Service

Discover the Next Identity Token Service: Your gateway to seamless OAuth 2.0 integration and secure scoped access

Next Identity Token Service is a stand-alone authorization service for integrating applications to consume scoped access. The token service uses the OAuth 2.0 framework to delegate tokens to relying parties (RPs), third parties, and downstream applications that have the authorization scope set based on that application’s permissions. An application that uses the Next Identity platform will be configured based on its integration type, and the token handed back to them will be scoped based on that set of scopes that it can then use against specific APIs.

Token types

The Next Identity Token Service can be configured to hand back an opaque token or a JWT. The choice between these token types depends on specific requirements and use cases.

An opaque access token is a random sequence of alphanumeric characters with no inherent meaning. Its validity and scope are checked against the authorization service. An opaque token can also be revoked to invalidate it.

Example:

"access_token": "151tR-O1wyuvH7jQ55bPHth96-VyqUIVcjQdrD-86o"

JWTs, in contrast, are not opaque. For more information about JWT and how to validate it, check our JWT Guide.

When to use JWT

  • Federation is desired. An app can authenticate using Next Identity and then present that token to a third-party IDP or application to be verified.
  • Improve performance that comes as a result of token self-validation.

When to use an opaque token

  • No federation is required in the API flow. The IDP that issues the token is the same entity that validates the token.
  • There is no need to allow the token bearer to inspect the claims within the token or use it to apply flexible policies.
  • There are specific scenarios when you explicitly need to revoke an access token before it expires. JWTs automatically expire based on the token expiry set at creation time.

Choosing the Grant Type

When making requests to the /token API, it's important to choose the appropriate grant_type based on your use case. Here are the two common grant types and their specific requirements:

  1. grant_type=authorization_code: Use this grant type when obtaining an access token after the user has authenticated. Include the code parameter in the request payload. The refresh_token parameter can also be included in this case, even though it is not required.
    Example Request:
    POST 'https://URL.com/idp/v1/account/token'
    {
        "client_id": "CLIENT_ID",
        "redirect_uri": "https://YOUR_APP/cb",
        "grant_type": "authorization_code",
        "code": "AUTHORIZATION_CODE_HERE",
        "auth_type": "email",
        "user_id": "EMAIL",
        "legal_acceptances": true,
        "scope": "openid email profile ni:external_systems"
    }
    
    Response:
    {
        "token_type": "Bearer",
        "access_token": "NPObrbntB3f7fDFlqSvqlnJi_w-VXbyguc2htf-Qh5s",
        "expires_in": 3600,
        "scope": "openid email profile ni:external_systems",
        "refresh_token": "l5ZQ2hroJYosLpcBxc4_JDaoWPc8VFTujEhmMM3XXRg",
        "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJmYW1pbHlfbmFtZSI6ICJEb2UiLAogICJnaXZlbl9uYW1lIjogIkphbmUiLAogICJ1cGRhdGVkX2F0IjogIjIwMTctMDMtMzBUMTU6MTM6NDAuNDc0WiIsCiAgImVtYWlsIjogImphbmUuZG9lQGVtYWlsLmNvbSIsCiAgImVtYWlsX3ZlcmlmaWVkIjogZmFsc2UsCiAgImlzcyI6ICJodHRwczovL0lEUF9ET01BSU4vIiwKICAic3ViIjogIlVVSUQiLAogICJhdWQiOiAiQ0xJRU5UX0lEIiwKICAiZXhwIjogMTI5MDkzMjgyMCwKICAiaWF0IjogMTI5MDgzODY4MjAKfQ==.jcN-CgREp2rd6ImXoY3P7Z9_b4OEQvnQcMgZEUqVmq_J_7cjkFZsdgoygix8vzciUIxVkh1hX33Wi6KUY3bPHsB4VEJ_Xjsqb0D2uLr0zq3Oov7Behq1ckgFt0pFMIOwdBA5nSOK_JUPe8snKvBWQkxI1sSXYxP2EbI9hHON4wxFrYDRwToANVdl6KTQKQH2j-Za7wkTLCeWjvRCV7Hlr2tjeBbskVAYEpnWxhnEpe9VcVJosl4JgP5zrS_yc3n2gIPaQsMp22MnrNtlaIHoPa4rt-aPCWiUdSOg62SeJz9k8E_eA5fpMQselihUQz1fgUX84ywy-FnWhN8D-m5hYw"
    }
    
  2. grant_type=refresh_token: Use this grant type when obtaining a new access token using a refresh token. Exclude the code parameter from the request payload.
    Example Request:
    POST 'https://URL.com/idp/v1/account/token'
    {
        "client_id": "CLIENT_ID",
        "redirect_uri": "https://YOUR_APP/cb",
        "grant_type": "refresh_token",
        "refresh_token": "REFRESH_TOKEN_HERE",
        "scope": "openid email profile ni:external_systems"
    }
    
    Response:
    {
        "token_type": "Bearer",
        "access_token": "NEW_ACCESS_TOKEN",
        "expires_in": 3600,
        "scope": "openid email profile ni:external_systems",
        "refresh_token": "NEW_REFRESH_TOKEN",
        "id_token": "NEW_ID_TOKEN"
    }
    
    Please ensure that you use the appropriate grant_type and include the required parameters in the request payload based on your use case to successfully obtain the desired access token.

Note: When using the client credential grant type, it is mandatory for the client to be of a confidential client type. Additionally, a user ID must always be provided.

📘

Summary for grant_type param

  • grant_type=authorization_code: Use this grant type when obtaining an access token after user authentication. Include the code parameter in the request payload. refresh_token parameter is optional.
  • grant_type=refresh_token: Use this grant type to obtain a new access token using a refresh token. Exclude the code parameter in the request payload.

By following these guidelines, you can ensure that your requests to the Next Identity Token Service are properly configured for the desired grant type.

Scopes

Token Scopes are a mechanism to limit an application's access to a user's account. An application can request one or more scopes, and the access token issued to the application will be limited to the scopes granted.

There are three types of scopes:

  • Standard scopes are pre-defined within the OAuth2.0 and OpenId Connect specifications and associated claims.
  • Custom scopes can be configured by the system and attached to the access token in the response. If the scopes are associated with a known system, custom claims can also be configured within those scopes.
  • Next Identity metadata scopes can be used to return data stored within the Next Identity Service, such as for external systems IDs.

Scopes and Claims in Authentication and Authorization

Scopes and claims play crucial roles in the processes of authentication and authorization.

Scopes determine the specific permissions or access levels an application requests during authentication. Each scope represents a set of user attributes, known as claims, which provide information about the user's identity and attributes.

For a more detailed understanding of how scopes and claims are utilized and managed within our system, we recommend referring to our comprehensive guide on Sessions, Tokens, and Custom Claims. This guide provides in-depth information on utilizing and managing scopes and claims.

Authentication example

Next, we are going to explore an example from beginning to end. In this example, we want to log the user in, then obtain some user data and permissions to access a restricted resource. We will use the authorization code flow for the authentication and then exchange the authorization code for the access token to see the requested scopes. Lastly, we will inspect the ID token for user details.

In this example, we want to authenticate a user and get the user's name, email, and external systems id information.

  1. Initiate the authentication flow by sending the user to the authorization URL:
https://URL.com/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=https://YOUR_APP/cb&
  scope=openid%20profile%20email%20ni:external_systems&
  state=STATE_VALUE

📘

Additional information on the scope parameter

The scope parameter includes three OIDC scope values:

  • openid: to obtain the id_token
  • profile: for given_name, family_name, and updated_at
  • email: to get email and email_verified
  • ni:external_systems: to get external systems
  1. The user authenticates and is redirected to your app with the authorization code in the URL.
  2. Grab the authorization code and call the /token endpoint to exchange the auth code for the access token:
POST 'https://URL.com/idp/v1/account/token'
{
    "client_id": "CLIENT_ID",
    "redirect_uri": "https://YOUR_APP/cb",
    "grant_type": "authorization_code",
    "code": "AUTHORIZATION_CODE_HERE",
    "auth_type": "email",
    "user_id": "EMAIL"
}

Response:

{
    "token_type": "Bearer",
    "access_token": "zMFfVikK0N8LCkZ4s_8Ps-84_OQv66gGy8PvFlEyRjs",
    "expires_in": 3600,
    "scope": "profile email ni:external_systems openid",
    "refresh_token": "quIyUXq4lTgpSoH79toMStti5FwusfGAgnUSOeoIyUs",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImM2YWY3ZDhmYzJmMjQ4OGE5MTY1NDJjMzI1N2ZkOWQ1In0.eyJzdWIiOiJhZDRkYzNiNC01ZGI0LTQ4ZWQtYjA4My03ZmQzMDM4YjJkMzMiLCJuYW1lIjoiSmFuZSIsImdpdmVuX25hbWUiOiJKYW5lIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJlbWFpbCI6ImphbmUuZG9lQGVtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJ1cGRhdGVkX2F0IjoiMjAyMy0xMC0wNCAxNzozMjozNi43NDA4MDYgKzAwMDAiLCJhdXRoX3RpbWUiOjE2OTY0NDA3NjAsImV4dGVybmFsX2lkcyI6eyJrZXljbG9hazAxIjp7ImFwcCI6IktleWNsb2FrIiwidXBkYXRlZCI6MTY5NjQ0MDcwOS4wLCJ1c2VyX2lkIjoiYWQ0ZGMzYjQtNWRiNC00OGVkLWIwODMtN2ZkMzAzOGIyZDMzIiwiY3JlYXRlZCI6MTY5NjQ0MDY0Ni4wLCJtaWdyYXRpb25fdHlwZSI6Im1pZ3JhdGVkIiwiZmlyc3RfbG9naW4iOmZhbHNlfX0sImlzcyI6Imh0dHBzOi8vaWQuZGV2LmV1Lm5leHRyZWFzb24uY29tIiwiYXVkIjoicWVjdWhrbnE3dmR0a3g1NDl2ejJxYWttaG5lYnI5OXoiLCJpYXQiOjE2OTY0NDA3NjAsImV4cCI6MTY5NjQ0MTA2MH0.Kd0P8owe-I_x9nu8TU4vOyEc_srijc4gwd-rwcdCDI4ofBWLKDWNVzsANhHemipZizAhzi7i5iz_XtN6cXyisfbX6MZR7dPUVrdzsTFSdHahq3qL_Rm_-LQUdx0Els9mZGm_syttm8fV5SMnZaMP76DRnB5HFdud92RQ1HaLZHhpQwl1va1EIrg1H3f7lm7xicBaqfQkBGPYVmtecxmIfUUPm-oA0OeEWQ3SjOkS5Si2eoWDXWNxpnx_wd5--DAbCt5WofglRxTBpR15MkuaMtwuZua8l327r5K-r0sH-d58jyzwq8M9Kk4ZmIvddWZjGGEkkkF1Rr0nHbJUL01Rxw"
}
  1. Extract the ID token from the response, decode it, and it will show the following claims:
{
   "sub": "UUID",
   "name": "Jane",
   "given_name": "Jane",
   "family_name": "Doe",
   "email": "[email protected]",
   "email_verified": true,
   "updated_at": "2023-10-04 17:32:36.740806 +0000",
   "auth_time": 1696440760,
   "external_ids": {
      "cognito-abc": {
         "app": "cognito",
         "user_id": "abcdefg1234567",
         "created": 1700603779,
         "migration_type": "sustained",
         "first_login": true
      },
      "keycloak-abc": {
         "app": "keycloak",
         "user_id": "1234567",
         "created": 1700603184,
         "migration_type": "migrated",
         "first_login": true
      }
   },
   "iss": "https://IDP_DOMAIN/",
   "aud": "CLIENT_ID",
   "iat": 1696440760,
   "exp": 1696441060
}

FAQ

  • Why do I not receive a refresh token when I use the client_credentials grant?
    The client_credentials grant_type creates non-refreshable tokens per https://datatracker.ietf.org/doc/html/rfc6749#section-4.4.3.

  • Can I configure my own arbitrary scopes?
    Yes. We recommend you follow the scope guide in this document for naming conventions and purpose.

  • Will scopes limit my ability to use my client ID?
    Not yet. Currently, scopes and claims are informational and are used to obtain user data and/or send a signal to an authorization application. However, the scope of a token doesn’t yet limit the functionality of that token against the IDP endpoints.

  • Does the token service support introspection?
    Yes, more details can be found about using the introspect endpoint in the reference documentation.