Definitive Guide

Extra Properties


1. Overview

Arbitrary properties can be associated with an access token.

Here, property is a JSON object which has entries named key and value. The types of the entry values are string. Literally, key represents the key of the property and value represents the value of the property.

The JSON below is an example of a property whose key and value are example_parameter and example_value, respectively.

{
    "key":"example_parameter",
    "value":"example_value"
}

For example, if the property above is associated with an access token, an access token response from your authorization server will look like the examples below.

Example in Implicit Flow

Location: http://localhost:8880/api/mock/redirection/5593494639
    #access_token=pNj1h24a4geA_YHilxrshkRkxJDsyXBZWKp3hZ5ND7A
    &token_type=Bearer&expires_in=86400&scope=
    &example_parameter=example_value

Example in Authorization Code Flow

{
    "access_token":"pNj1h24a4geA_YHilxrshkRkxJDsyXBZWKp3hZ5ND7A",
    "token_type":"Bearer",
    "expires_in":86400,
    "scope":null,
    "example_parameter":"example_value"
}

As you can see, a property, example_parameter=example_value, is included in the redirect URI in "Example in Implicit Flow" and in the JSON in "Example in Authorization Code Flow". The property is passed to the client application. However, there may be some cases where you want to associate properties with an access token but don't want to show them to the client application. In such a case, add hidden=true like below when you prepare a property.

{
    "key":"example_parameter",
    "value":"example_value",
    "hidden":true
}

Properties associated with an access token can be obtained by using Authlete's /api/auth/introspection API (which is the API to get information about an access token). A response from the introspection API contains associated properties in the format as shown below.

{
    "type":"introspectionResponse",
    "resultCode":"A056001",
    "resultMessage":"[A056001] The access token is valid.",
    "action":"OK",
    "clientId":5008706718,
    "existent":true,
    "expiresAt":1461369117000,
    "properties":[
        {
            "hidden":false,
            "key":"example_parameter",
            "value":"example_value"
        }
    ],
    "refreshable":false,
    "responseContent":"Bearer error=\"invalid_request\"",
    "subject":"user123",
    "sufficient":true,
    "usable":true
}

Note that the response from Authlete's introspection API is different from the format defined in RFC 7662 See 4. Introspect Access Token in Authlete Definitive Guide for details.


2. Restrictions

  1. The keys listed below are not allowed to be used as property keys. They are ignored on the server side even if given. The reason is that they are reserved in RFC 6749 and OpenID Connect Core 1.0 as parameter names used in responses from an authorization server.

    • access_token
    • token_type
    • expires_in
    • refresh_token
    • scope
    • error
    • error_description
    • error_uri
    • id_token
  2. The only allowed type of property values is string. Boolean, array and other types cannot be used.

  3. There is a length limitation. Properties are saved into the database on the seriver side after going through the steps described below.

    1. Converted to a two-dimensional array (e.g. [["example_parameter","example_value",null]])
      (The value of hidden is converted to either null or an empty string. They mean false and true, respectively.)
    2. Converted to JSON (e.g. "[[\"example_parameter\":\"example_value\",null]]")
    3. Encrypted by AES/CBC/PKCS5Padding
    4. Encoded by base64url

    If the length of the resultant base64url string generated by the above steps exceeds 65535, an error occurs.


3. How to simulate Implicit Flow by curl

  1. Pass a request from a client to an authorization endpoint, "client_id=5008706718&response_type=token", to /api/auth/authorization API.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/authorization \
      -d "parameters=client_id%3D5008706718%26response_type%3Dtoken"

    Extract the value of ticket from the lengthy JSON response. The ticket is used to call /api/auth/authorization/issue API later.

  2. Issue an access token by calling /api/auth/authorization/issue API. Here, specify properties to associate with an access token using properties parameter.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/authorization/issue \
      -H 'Content-Type:application/json' \
      -d "{\"ticket\":\"1iIR-GMmBLLQLC-tJ70Wmb83UKAB2V8WnhwsVWlGJr8\",\"subject\":\"user123\",\"properties\":[{\"key\":\"example_parameter\",\"value\":\"example_value\"}]}"

    A JSON response like below is returned.

    {
        "type":"authorizationIssueResponse",
        "resultCode":"A040001",
        "resultMessage":"[A040001] The authorization request was processed successfully.",
        "action":"LOCATION",
        "responseContent":"http://localhost:8880/api/mock/redirection/5593494639#access_token=pNj1h24a4geA_YHilxrshkRkxJDsyXBZWKp3hZ5ND7A&token_type=Bearer&expires_in=86400&scope=&example_parameter=example_value"
    }
  3. As the value of action contained in the above response from /api/auth/authorization/issue API is LOCATION, HTTP status "302 Found" should be returned to the client application. When the value of action contained in a response from /api/auth/authorization/issue API is LOCATION, the value of responseContent is the value that should be used as the value of Location HTTP header. Using these pieces of information, a response like below should be returned to the client application.

    HTTP/1.1 302 Found
    Location: http://localhost:8880/api/mock/redirection/5593494639
        #access_token=pNj1h24a4geA_YHilxrshkRkxJDsyXBZWKp3hZ5ND7A
        &token_type=Bearer&expires_in=86400&scope=
        &example_parameter=example_value
    Cache-Control: no-store
    Pragma: no-cache

    Note that this response contains example_parameter=example_value as an additional parameter.

  4. Information about the issued access token can be obtained by calling /api/auth/introspection API like below.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/introspection \
      -d token=pNj1h24a4geA_YHilxrshkRkxJDsyXBZWKp3hZ5ND7A

    Below is an example from the introspection API.

    {
        "type":"introspectionResponse",
        "resultCode":"A056001",
        "resultMessage":"[A056001] The access token is valid.",
        "action":"OK",
        "clientId":5008706718,
        "existent":true,
        "expiresAt":1461369117000,
        "properties":[
            {
                "hidden":false,
                "key":"example_parameter",
                "value":"example_value"
            }
        ],
        "refreshable":false,
        "responseContent":"Bearer error=\"invalid_request\"",
        "subject":"user123",
        "sufficient":true,
        "usable":true
    }

4. How to simulate Authorization Code Flow by curl

  1. Pass a request from a client to an authorization endpoint, "client_id=5008706718&response_type=code", to /api/auth/authorization API.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/authorization \
      -d "parameters=client_id%3D5008706718%26response_type%3Dcode"

    Extract the value of ticket from the lengthy JSON response. The ticket is used to call /api/auth/authorization/issue API later.

  2. Issue an authorization code by calling /api/auth/authorization/issue API. Here, specify properties to associate with an authorization code using properties parameter. The specified properties will finally be associated with an access token. Note that additional properties can be passed to /api/auth/token API which will be called later, too. Therefore, in the authorization code flow, properties don't necessarily have to be given to /api/auth/authorization/issue API even if properties need to be associated with an access token.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/authorization/issue \
      -H 'Content-Type:application/json' \
      -d "{\"ticket\":\"xKdGvPyPkLJRkmP6MSAJ1wISBmdnSbPG8pFzgTdZh4U\",\"subject\":\"user123\",\"properties\":[{\"key\":\"example_parameter\",\"value\":\"example_value\"}]}"

    A JSON like below is returned.

    {
        "type":"authorizationIssueResponse",
        "resultCode":"A040001",
        "resultMessage":"[A040001] The authorization request was processed successfully.",
        "action":"LOCATION",
        "responseContent":"http://localhost:8880/api/mock/redirection/5593494639?code=n96DtM32eV8maSG5Z3_p3qhAT7zuvuqlAaizOmDInZ4"
    }
  3. As the value of action contained in the above response from /api/auth/authorization/issue API is LOCATION, HTTP status "302 Found" should be returned to the client application. When the value of action contained in a response from /api/auth/authorization/issue API is LOCATION, the value of responseContent is the value that should be used as the value of Location HTTP header. Using these pieces of information, a response like below should be returned to the client application.

    HTTP/1.1 302 Found
    Location: http://localhost:8880/api/mock/redirection/5593494639?code=n96DtM32eV8maSG5Z3_p3qhAT7zuvuqlAaizOmDInZ4
    Cache-Control: no-store
    Pragma: no-cache
  4. Pass a request from a client to a token endpoint, "code=n96DtM32eV8maSG5Z3_p3qhAT7zuvuqlAaizOmDInZ4&grant_type=authorization_code", to /api/auth/token API. Note that an additional property to associate with an access token, additional_parameter=additional_value, is specified here. If there are duplicated key names in properties passed to /api/auth/authorization/issue API and those passed to /api/auth/token API, ones passed to /api/auth/token API will overwrite those passed to /api/auth/authorization/issue API.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/token \
      -H 'Content-Type:application/json' \
      -d "{\"parameters\":\"code=n96DtM32eV8maSG5Z3_p3qhAT7zuvuqlAaizOmDInZ4&grant_type=authorization_code\",\"properties\":[{\"key\":\"additional_parameter\",\"value\":\"additional_value\"}]}"

    A JSON like below is returned.

    {
        "type":"tokenResponse",
        "resultCode":"A050001",
        "resultMessage":"[A050001] The token request (grant_type=authorization_code) was processed successfully.",
        "action":"OK",
        "responseContent":"{\"access_token\":\"xuc8cd1zf9TpdMwiB7sfLcPmY6DHpYIpz1jyo9a0YXs\",\"additional_parameter\":\"additional_value\",\"refresh_token\":\"66fIuQ33usvJ9ZSDrnUv2KQnC946Kr4Cj8n8bcjlpTI\",\"example_parameter\":\"example_value\",\"scope\":null,\"token_type\":\"Bearer\",\"expires_in\":86400}"
    }
  5. As the value of action contained in the above response from /api/auth/token API is OK, HTTP status "200 OK" should be returned to the client application. When the value of action contained in a response from /api/auth/token API is OK, the value of responseContent is the value that should be used as the value of the response body. Using these pieces of information, a response like below should be returned to the client application.

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    Pragma: no-cache
    
    {
        "access_token":"xuc8cd1zf9TpdMwiB7sfLcPmY6DHpYIpz1jyo9a0YXs",
        "additional_parameter":"additional_value",
        "refresh_token":"66fIuQ33usvJ9ZSDrnUv2KQnC946Kr4Cj8n8bcjlpTI",
        "example_parameter":"example_value",
        "scope":null,
        "token_type":"Bearer",
        "expires_in":86400
    }

    In this response, the property given to /api/auth/authorization/issue API (example_parameter=example_value) and the property given to /api/auth/token API (additional_parameter=additional_value) are contained.


5. How to simulate Client Credentials Flow by curl

  1. Pass a request from a client to a token endpoint, grant_type=client_credentials&client_id=5008706718, to /api/auth/token API. Use properties parameter to specify properties to associate with an access token. Note that the client type of the client application must be confidential in order to use Client Credentials Flow.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/token \
      -H 'Content-Type:application/json' \
      -d "{\"parameters\":\"grant_type=client_credentials&client_id=5008706718&client_secret=zVI5JjIKw4W2XIF7o8GLzaUOs4jAx_OhuWf7ol-lAMpMrzm574zmnhgzOTDApSHgUD4LKv41aD43p0gU4Hz67w\",\"properties\":[{\"key\":\"example_parameter\",\"value\":\"example_value\"}]}"

    A JSON like below is returned.

    {
        "type":"tokenResponse",
        "resultCode":"A052001",
        "resultMessage":"[A052001] The token request (grant_type=client_credentials) was processed successfully.",
        "action":"OK",
        "responseContent":"{\"access_token\":\"8PKs66MYc1nRVUcdE5wmEr3gn3lQ9FtcxRQWY3ts-fw\",\"example_parameter\":\"example_value\",\"scope\":null,\"token_type\":\"Bearer\",\"expires_in\":86400}"
    }
  2. As the value of action contained in the above response from /api/auth/token API is OK, HTTP status "200 OK" should be returned to the client application. When the value of action contained in a response from /api/auth/token API is OK, the value of responseContent is the value that should be used as the value of the response body. Using these pieces of information, a response like below should be returned to the client application.

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    Pragma: no-cache
    
    {
        "access_token":"8PKs66MYc1nRVUcdE5wmEr3gn3lQ9FtcxRQWY3ts-fw",
        "example_parameter":"example_value",
        "scope":null,
        "token_type":"Bearer",
        "expires_in":86400
    }

    In Client Credentials Flow, a refresh token (refresh_token) is not issued. See RFC 6749 for details.


6. How to simulate Resource Owner Password Credentials Flow by curl

  1. Pass a request from a client to a token endpoint, grant_type=password&client_id=5008706718&username=u&password=p, to /api/auth/token API. When grant_type is password, the value of properties parameter given to /api/auth/token API is simply discarded. So, it is not specified here. Instead, properties parameter is used later when /api/auth/token/issue API is called. Note that /api/auth/token/issue API exists only for grant_type=password.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/token \
      -H 'Content-Type:application/json' \
      -d "{\"parameters\":\"grant_type=password&client_id=5008706718&username=u&password=p\"}"

    A JSON like below is returned.

    {
        "type":"tokenResponse",
        "resultCode":"A051001",
        "resultMessage":"[A051001] Authlete has successfully issued a ticket to the service (API Key = 5593494639) for the token request from the client (ID = 5008706718). [grant_type=password]",
        "action":"PASSWORD",
        "password":"p",
        "ticket":"qdPziRKfjuHkaTbCQ5r0lBeR3pwJxCnEKrdPv5zbfRI",
        "username":"u"
    }
  2. When the value of action in a response from /api/auth/token API is PASSWORD, it means that Resource Owner Password Credentials Flow is being used. In this case, as the first step, user authentication needs to be performed using username and password presented by the client application. The values of username parameter and password parameter in the original token request are contained in a response from /api/auth/token API without any modification. In the above example, the value of username is u and that of password is p.

  3. As a result of user authentication, the unique identifier of the user should be determined. Call /api/auth/token/issue API with the unique identifier as the value of subject parameter. Also, the API call requires ticket which has been issued from /api/auth/token API in advance. If some properties need to be associated with an access token, properties request parameter should be added, too.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/token/issue \
      -H 'Content-Type:application/json' \
      -d "{\"ticket\":\"qdPziRKfjuHkaTbCQ5r0lBeR3pwJxCnEKrdPv5zbfRI\",\"subject\":\"user123\",\"properties\":[{\"key\":\"example_parameter\",\"value\":\"example_value\"}]}"

    A JSON like below is returned.

    {
        "type":"tokenIssueResponse",
        "resultCode":"A054001",
        "resultMessage":"[A054001] The token request (grant_type=password) was processed successfully.",
        "action":"OK",
        "responseContent":"{\"access_token\":\"jUmm2CSQGHb4OuUIGabdsqL1S0KNJWlZrP5lDNDEWX0\",\"refresh_token\":\"Q4OAafrltI5khG0Ur6c6XuJVQ1IU5Tjrk2sqD2sfKCo\",\"example_parameter\":\"example_value\",\"scope\":null,\"token_type\":\"Bearer\",\"expires_in\":86400}"
    }
  4. As the value of action contained in the above response from /api/auth/token/issue API is OK, HTTP status "200 OK" should be returned to the client application. When the value of action contained in a response from /api/auth/token/issue API is OK, the value of responseContent is the value that should be used as the value of the response body. Using these pieces of information, a response like below should be returned to the client application.

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    Pragma: no-cache
    
    {
        "access_token":"jUmm2CSQGHb4OuUIGabdsqL1S0KNJWlZrP5lDNDEWX0",
        "refresh_token":"Q4OAafrltI5khG0Ur6c6XuJVQ1IU5Tjrk2sqD2sfKCo",
        "example_parameter":"example_value",
        "scope":null,
        "token_type":"Bearer",
        "expires_in":86400
    }

7. How to simulate Refresh Token Flow by curl

  1. Pass a request from a client to a token endpoint, refresh_token=66fIuQ33usvJ9ZSDrnUv2KQnC946Kr4Cj8n8bcjlpTI&grant_type=refresh_token, to /api/auth/token API. Properties to associate with an access token should be specified using properties parameter. In this example, the property is extra_parameter=extra_value and this is a bit different from example properties used so far.

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/token \
      -H 'Content-Type:application/json' \
      -d "{\"parameters\":\"refresh_token=66fIuQ33usvJ9ZSDrnUv2KQnC946Kr4Cj8n8bcjlpTI&grant_type=refresh_token\",\"properties\":[{\"key\":\"extra_parameter\",\"value\":\"extra_value\"}]}"

    A JSON like below is returned.

    {
        "type":"tokenResponse",
        "resultCode":"A053001",
        "resultMessage":"[A053001] The token request (grant_type=refresh_token) was processed successfully.",
        "action":"OK",
        "responseContent":"{\"access_token\":\"KQfuhsimWoOaTZVRYbzh166pqK49hQyNMGTbbN8UfUY\",\"additional_parameter\":\"additional_value\",\"refresh_token\":\"CdcL3Ixx5EIn2KK3ChDKUgoY_nf-1rHad7Z8Xk_O5s0\",\"example_parameter\":\"example_value\",\"extra_parameter\":\"extra_value\",\"scope\":null,\"token_type\":\"Bearer\",\"expires_in\":86400}"
    }

    When grant_type is refresh_token, properties passed to /api/auth/token API are treated as additional properties for the access token which is coupled with the presented refresh token. The value of refresh_token parameter in the above example is the refresh token which has been issued as a result of "7. How to simulate Authorization Code Flow by curl". And the access token which is coupled with the refresh token already has two properties, example_parameter=example_value and additional_parameter=additional_value. Therefore, as a result of adding extra_parameter=extra_value on /api/auth/token API call, a newly issued access token will have three properties.

  2. As the value of action contained in the above response from /api/auth/token API is OK, HTTP status "200 OK" should be returned to the client application. When the value of action contained in a response from /api/auth/token API is OK, the value of responseContent is the value that should be used as the value of the response body. Using these pieces of information, a response like below should be returned to the client application.

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    Pragma: no-cache
    
    {
        "access_token":"KQfuhsimWoOaTZVRYbzh166pqK49hQyNMGTbbN8UfUY",
        "additional_parameter":"additional_value",
        "refresh_token":"CdcL3Ixx5EIn2KK3ChDKUgoY_nf-1rHad7Z8Xk_O5s0",
        "example_parameter":"example_value",
        "extra_parameter":"extra_value",
        "scope":null,
        "token_type":"Bearer",
        "expires_in":86400
    }
  3. Passing the newly issued access token to the introspection API:

    curl -s -v \
      --user 5593494639:AAw0rner_-y1A6J9s20wjRCpkBvez3GxEBoL9jOJVR0 \
      http://localhost:8880/api/auth/introspection \
      -d token=KQfuhsimWoOaTZVRYbzh166pqK49hQyNMGTbbN8UfUY

    will result in a response like below. Three properties are embedded in the response.

    {
        "type":"introspectionResponse",
        "resultCode":"A056001",
        "resultMessage":"[A056001] The access token is valid.",
        "action":"OK",
        "clientId":5008706718,
        "existent":true,
        "expiresAt":1461519667000,
        "properties":[
            {
                "hidden":false,
                "key":"example_parameter",
                "value":"example_value"
            },
            {
                "hidden":false,
                "key":"additional_parameter",
                "value":"additional_value"
            },
            {
                "hidden":false,
                "key":"extra_parameter",
                "value":"extra_value"
            }
        ],
        "refreshable":true,
        "responseContent":"Bearer error=\"invalid_request\"",
        "subject":"user123",
        "sufficient":true,
        "usable":true
    }