Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.authlete.com/llms.txt

Use this file to discover all available pages before exploring further.

Introduction

the original mechanism on OAuth 2 framework for expressing authorizations is the scopes presented on the token by the subject to the token holder. That allowed many enterprises and adopters to properly secured their environments when there is no ambiguity of the resource that the token is about. Today with the micro service architecture and data partition due to data residency requirements or data sharding, the resource that the grant is about needs to be increasingly precise identified on the request, token and introspection. There are 2 specifications addressing this: the Resource Identifier (RFC 8707) and the Rich Authorization Requests (RFC 9396). This note is about the Resource Identifier specification and the support that Authlete provides. The resource identifier specification extends the authorization requests by introducing the “resource” parameter. This parameter can be included on authorization request parameters, Request Objects or the body of the push authorization requests or token requests.

Basic flow

Authorization Request

The authorization requests, pushed or not and wrapped or not on a Request Object can single or multi valued. The request below is an example of API request to ask Authlete to process an authorization request that includes two resources specified by using the parameter resource.
curl --request POST 'https://api.authlete.com/api/auth/authorization' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic OXXXXXXXXXXE=' \
--data '{
  "parameters":
    "client_id=4015029369818770&
     scope=openid&
     response_type=code&
     redirect_uri=https%3A%2F%2Fmobile.example.com%2Fcb&
     code_challenge=OJeFyctrNbrZKVR60DQhAMqN6X_q00x7koQWAMZivnI&
     code_challenge_method=S256&
     resource=https%3A%2F%2Fapi.example.com%2Fapp%2F&
     resource=https%3A%2F%2Fcontacts.example.com%2F" }'
The response from Authlete includes the resources attribute that will be used by the AS to decide if the authorization request is valid and if the user can grant access to those resources.
{
    "type": "authorizationResponse",
    "resultCode": "A004001",
    "resultMessage": "[A004001] Authlete has successfully issued a ticket to the service (API Key = 974410533989) for the authorization request from the client (ID = 4015029369818770). [response_type=code, openid=true]",
    "action": "INTERACTION",
    ...
    "resources": [
        "https://api.example.com/app/",
        "https://contacts.example.com/"
    ],    ...
    "ticket": "GKXW-NWoXHEH8Xh2lOVXbImFKZF3NY-yfpxMdqvwsms"
}

Token Request

The AS sends token request content with the authorization code to Authlete.
curl --request POST 'https://api.authlete.com/api/auth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic OXXXXXXXXXXVlE=' \
--data '{
   "parameters": "grant_type=authorization_code&
                  code=R9eLSo9quzYjjO8zdlqFMAMdqkBz0vthmZWUDRpQw2s&
                  redirect_uri=https%3A%2F%2Fmobile.example.com%2Fcb&
                  code_verifier=_OtZIlJuuFwniie_nb6A172G2576YD_NwppB-I2ezfY",
   "clientId" : "4015029369818770"
   }'
The response will extract the resources that are granted to the client and include them in accessTokenResources.
{
    "type": "tokenResponse",
    "resultCode": "A050001",
    "resultMessage": "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
    "accessToken": "FOMxkE5baqGjIAznqmhANgw1ITiwCK4CRdo0Pbi2p-A",
    "accessTokenResources": [
        "https://api.example.com/app/",
        "https://contacts.example.com/"
    ],    ...
    "grantType": "AUTHORIZATION_CODE",
    "idToken": "eyJraWQiOiIzIiwiYWxnIjoiUlMyNTYifQ.eyJjcGYiOiIwNDAxOTg3NTE1NCIsIm5hbWUiOiJEci4gQmV2ZXJseSBQYWNvY2hhIiwiZW1haWwiOiJCZXJuaWVjZTE1QGhvdG1haWwuY29tIiwiaXNzIjoiaHR0cHM6Ly9hdXRobGV0ZS5jb20iLCJzdWIiOiJCZXJuaWVjZTE1QGhvdG1haWwuY29tIiwiYXVkIjpbIjQwMTUwMjkzNjk4MTg3NzAiXSwiZXhwIjoyNTM0MDIxMjgwMDAsImlhdCI6MTYyODI3ODE2MH0.MGIEUwzFOiySL1klpCrGgcP7u70J1lGuxM154WV8l6HuGRlDbul8RsjjqkM-cZrX-wohWnXr4keqoQ8uJAEJwIuSL3Szt8KNpFD6fDwNfYC6SL_cTO1va3sgLSmDH7xnvaLfDMEedidw5-DPCYXg9r6jBAkixTkeSPbjZXgMkk44a6kq17TA0nRO2HZ_KNB-ewhjTpQhwrTxOoPtH-ThwOqUSg7DQfSndlcm-yBWE0ZveGj3m5MbwQhzqt6qokQN8bgbAsPMVDF34gM613v_kEWCiiI3iWzIDjGfJ0nzPZTjm7q8MDGRaSKIEXI98XDhyv-Ah4dQiIMYLuP48tz-xg",
    "responseContent": "{\"access_token\":\"FOMxkE5baqGjIAznqmhANgw1ITiwCK4CRdo0Pbi2p-A\",\"scope\":\"openid\",\"id_token\":\"eyJraWQiOiIzIiwiYWxnIjoiUlMyNTYifQ.eyJjcGYiOiIwNDAxOTg3NTE1NCIsIm5hbWUiOiJEci4gQmV2ZXJseSBQYWNvY2hhIiwiZW1haWwiOiJCZXJuaWVjZTE1QGhvdG1haWwuY29tIiwiaXNzIjoiaHR0cHM6Ly9hdXRobGV0ZS5jb20iLCJzdWIiOiJCZXJuaWVjZTE1QGhvdG1haWwuY29tIiwiYXVkIjpbIjQwMTUwMjkzNjk4MTg3NzAiXSwiZXhwIjoyNTM0MDIxMjgwMDAsImlhdCI6MTYyODI3ODE2MH0.MGIEUwzFOiySL1klpCrGgcP7u70J1lGuxM154WV8l6HuGRlDbul8RsjjqkM-cZrX-wohWnXr4keqoQ8uJAEJwIuSL3Szt8KNpFD6fDwNfYC6SL_cTO1va3sgLSmDH7xnvaLfDMEedidw5-DPCYXg9r6jBAkixTkeSPbjZXgMkk44a6kq17TA0nRO2HZ_KNB-ewhjTpQhwrTxOoPtH-ThwOqUSg7DQfSndlcm-yBWE0ZveGj3m5MbwQhzqt6qokQN8bgbAsPMVDF34gM613v_kEWCiiI3iWzIDjGfJ0nzPZTjm7q8MDGRaSKIEXI98XDhyv-Ah4dQiIMYLuP48tz-xg\",\"token_type\":\"Bearer\",\"expires_in\":86400}"
}
Note that the resource list are encoded into the access token (when you are using JWT-Based Access Tokens) and are not included on ID token, as the intent of the ID token is not to be user as Bearer token when accessing the APIs.

Introspection Request

When the access token is presented to a resource server (RS), the RS can use the introspection endpoint to query the resources list and therefore fulfill or not the request. The request below is an example of API request by the AS, asking Authlete API to process an introspection request from the RS to the AS.
curl --request POST 'https://api.authlete.com/api/auth/introspection/standard' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic OXXXXXXXXXXXXXXX=' \
--data '{ "parameters": "token=FOMxkE5baqGjIAznqmhANgw1ITiwCK4CRdo0Pbi2p-A"
}'
A sample response is as follows, note the aud attribute that includes the list of resources that the access token is about.
{
    "type": "standardIntrospectionResponse",
    "resultCode": "A145001",
    "resultMessage": "[A145001] Introspection was performed successfully (type=access_token, active=true).",
    "action": "OK",
    "responseContent":
        "{\"sub\":\"Berniece15@hotmail.com\",
          \"aud\":[\"https://api.example.com/app/\",
                   \"https://contacts.example.com/\"],
          \"scope\":\"openid\",
          \"iss\":\"https://authlete.com\",
          \"active\":true,
          \"token_type\":\"Bearer\",
          \"exp\":1628364560,
          \"client_id\":\"4015029369818770\"}"
}

Narrowing the resource during token request

The Resource Indicators specification creates the option for the client narrowing the list of resources that it is targeting. Let’s say the client has requested the authorization to resources “https://api.example.com/customers/”, “https://api.example.com/orders/” and “https://api.example.com/inventory/”, and the authorization for all those resources is granted. As long as the authorization retains, the client can request an access token restricted to “https://api.example.com/orders/” to run a specific use case and later request another access token to a different resource list. The sequence below of requests shows an API client creating an access token for two resources.
curl --request POST 'https://api.authlete.com/api/auth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic OXXXXXX=' \
--data '{
   "parameters": "grant_type=authorization_code&
                  code=HEEutGTtpXDVD_3FcRATvshyqMgTsfhdcBFjy2TE3ro&
                  redirect_uri=https%3A%2F%2Fmobile.example.com%2Fcb&
                  code_verifier=XTzm4vHHPQXWUI45M1wJMiIO3oF5sZz6OhKWEvFdsG0",
   "clientId" : "4015046106493768"
}'

{
    "type": "tokenResponse",
    "resultCode": "A050001",
    "resultMessage": "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
    "accessToken": "4Ntb16h21_nFrc637_vXF-3HfR1g8or3646o4cAVyNE",
    "accessTokenResources": [
        "https://api.example.com/app/",
        "https://contacts.example.com/"
    ],**    ...
    "subject": "Bonita89@yahoo.com"
}
The second request creates an access token specific to the “https://contacts.example.com/”.
curl --location --request POST 'https://api.authlete.com/api/auth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic OXXXXXX=' \
--data-raw '{
   "parameters": "grant_type=refresh_token&
                  refresh_token=JWmEeN5BtBTL0um-pB9diYlJP5LRr7YREAJ8XrqY8CQ&
                  redirect_uri=https%3A%2F%2Fmobile.example.com%2Fcb&
                  resource=https%3A%2F%2Fcontacts.example.com%2F",   "clientId" : "4015046106493768"
}'

{
    "type": "tokenResponse",
    "resultCode": "A053001",
    "resultMessage": "[A053001] The token request (grant_type=refresh_token) was processed successfully.",
    "accessToken": "5XvZzUjduXQInKi5ywyj7hP0dScDmfhMmp_yl-fSKDI",

    "accessTokenResources": [
        "https://contacts.example.com/"
    ],
    "resources": [
        "https://contacts.example.com/"
    ],**    "subject": "Bonita89@yahoo.com"
}
And later the same client changes the token to “https://api.example.com/app/.
curl --location --request POST 'https://api.authlete.com/api/auth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic OXXXXXX=' \
--data-raw '{
   "parameters": "grant_type=refresh_token&
                  refresh_token=JWmEeN5BtBTL0um-pB9diYlJP5LRr7YREAJ8XrqY8CQ&
                  redirect_uri=https%3A%2F%2Fmobile.example.com%2Fcb&
                  resource=https%3A%2F%2Fapi.example.com%2Fapp%2F",
   "clientId" : "4015046106493768"
}'

{
    "type": "tokenResponse",
    "resultCode": "A053001",
    "resultMessage": "[A053001] The token request (grant_type=refresh_token) was processed successfully.",
    "accessToken": "W_g41P7zgGMW8TtYdb32sg9pBD7IthLQKFTP7hrB7ZY",
    "accessTokenResources": [
        "https://api.example.com/app/"
    ],
    "resources": [
        "https://api.example.com/app/"
    ],**    ...
    "subject": "Bonita89@yahoo.com"
}
If you are planning to use this feature, check if the single access token per subject is enabled. if that is the case, the access token will be invalidated when the refresh token is used. In your example, when the second request is done, the access token from the first became invalid. When the 3rd call is done, the access token of the 2nd call is invalidated.