Enabling “device flow”

Enabling “device flow”

Preface

“Device flow,” defined in RFC 8628 (OAuth 2.0 Device Authorization Grant) , is an authorization flow to issue access tokens for API clients running on devices with no Web browsers and/or that have limited capability for inputting text, with end user consent.

This article describes component architecture of an authorization server using Authlete to support the device flow and instructions to configure Authlete.

This feature is available in Authlete version 2.1 and later.

How an Authorization Server Supports the Device Flow Using Authlete API

An authorization server must have the following endpoints and “verification URI” to support the device flow. Authlete provides functions as APIs for implementing them.

enabling-device-flow_1

Configuration Settings

This section explains settings for enabling the device flow. You have to configure both Authlete service and its client that uses the flow.

Authlete Service Settings

Configure the following settings in the Authlete Management Console

Tab Item Value
Service Settings > Endpoints > Global Settings Supported Grant Types Enable “DEVICE_CODE
Service Settings > Endpoints > Advanced > Device Flow Device Authorization Endpoint The URL of the device authorization endpoint
e.g. https://as.example.com/device_authorization
Service Settings > Endpoints > Advanced > Device Flow Verification URI The value of verification_uri to be presented to end users
e.g. https://as.example.com/device
Service Settings > Endpoints > Advanced > Device Flow Verification URI with Placeholder The value of verification_uri_complete to be presented to end users (typically using QR code etc.)
e.g. https://as.example.com/device?user_code=USER_CODE
Service Settings > Endpoints > Advanced > Device Flow Verification Code Duration The duration of device_code and user_code in seconds
e.g. 600
Service Settings > Endpoints > Advanced > Device Flow Polling Interval The minimum interval between polling requests to the token endpoint in seconds
e.g. 5
Service Settings > Endpoints > Advanced > Device Flow User Code Character Set The character set for user_code
e.g. BASE20
Service Settings > Endpoints > Advanced > Device Flow User Code Length The length of user_code
e.g. 8

To configure the service supported grant types:

  1. Log in to the Authlete Management Console
  2. Click on your Organization name and choose your Service.
  3. Navigate to Service Settings > Endpoints > Global Settings
  4. Under the Supported Grant Types section, select the DEVICE_CODE checkbox.
  5. Click Save Changes to update your service settings.
enabling-device-flow_2

To configure the service device flow settings:

  1. Log in to the Authlete Management Console
  2. Click on your Organization name and choose your Service.
  3. Navigate to Service Settings > Endpoints > Advanced > Device Flow
  4. Configure the following values:
    • Device Authorization Endpoint URL
    • Verification URI
    • Verification URI with Placeholder
    • Verification Code Duration
    • Polling Interval
    • User Code Character Set
    • User Code Length
  5. Click Save Changes to update your service settings.
enabling-device-flow_3

Authlete Client Settings

Configure the following in Client Settings.

Tab Key Value
Basic Client Type PUBLIC
Authorization Grant Types Enable “DEVICE_CODE
Authorization [Token  Endpoint]Client Authentication Method Choose “NONE

In this article, the device is assumed to be a non-confidential client . Choose appropriate values for Client Type and Client Authentication Method if devices in your environment are confidential clients.

To Configure Basic Settings:

  1. Navigate to Client Settings > Basic Settings > General
  2. For Client Type, choose the PUBLIC radio button.
  3. Click Save Changes to apply the updates.
enabling-device-flow_4

To Configure Grant Types:

  1. Navigate to Client Settings > Endpoints > Global Settings > General
  2. Under the Supported Grant Types section, select the DEVICE_CODE checkbox.
  3. Click Save Changes to apply the updates.
enabling-device-flow_5

To Configure Token Endpoints:

  1. Navigate to Client Settings > Endpoints > Token > General
  2. Under the Client Authentication Method section, open the dropdown menu and select NONE
  3. Click Save Changes to apply the updates.
enabling-device-flow_6

Example

This example shows how an authorization server using Authlete responds to a device authorization request from a client, verifies a user_code from an end user, and responds token requests from the client.

device-flow-2
Device Flow Diagram

Device authorization request

Assume the client makes the following “device authorization request” to the authorization server  (step #2 in Device Flow Diagram). (all examples below are folded for readability)

POST /device_authorization HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
...
client_id=...&scope=openid+profile+read

The authorization server forwards the request content to Authlete’s /device/authorization API (step #3, #4).

  • Request (step #3 in Device Flow Diagram using curl command)
curl -v -X POST https://us.authlete.com/api/21653835348762/device/authorization \
   -H 'Authorization: Bearer V5a40R6********C*******95q4HC0Z-T0YKD9-nR6F' \
   -H 'Content-type: application/json' \
   -d '{"parameters": "client\_id=...&scope=openid+profile+read
"}'
  • Response (step #4 in Device Flow Diagram)
{
  "type": "deviceAuthorizationResponse",
  "resultCode": "A220001",
  "resultMessage":
    "[A220001] The device authorization request was
     processed successfully.",
  "action": "OK",
  "deviceCode":
    "-jxwQ_7MEdR3SqS86bEg1ONUYdwGmSYjqH8eIBZ1c3U",
  "responseContent":
    "{\"user_code\":\"TXBBPHDZ\",
      \"device_code\":
        \"-jxwQ_7MEdR3SqS86bEg1ONUYdwGmSYjqH8eIBZ1c3U\",
      \"interval\":5,
      \"verification_uri_complete\":
        \"https://as.example.com/device?user_code=TXBBPHDZ\",
      \"verification_uri\":
        \"https://as.example.com/device\",
      \"expires_in\":600}",
  "userCode": "TXBBPHDZ",
  "verificationUri":
    "https://as.example.com/device",
  "verificationUriComplete":
    "https://as.example.com/device?user_code=TXBBPHDZ",
...
}

The authorization server extracts the value of “responseContent” and sends it back to the client as a device authorization response (step #5 in Device Flow Diagram. Details omitted).

“Verification URI”

Verifying the user_code

The client will send “device access token requests” to the server. The requests include the value of “device_code” extracted from the server’s device authorization response (described later in this section).

Concurrently with the token requests, the client will ask the end user to present the value of “user_code” (extracted from the device authorization response) at ”Verification URI” of the authorization server  (step #6 in Device Flow Diagram).

How the code is shown to the user is up to the client. The following example is to present the code along with the value of “verification_uri” to the end user (based on an example in RFC 8628 ).

+-----------------------------------------------+
|                                               |
|  Using a browser on another device, visit:    |
|  https://as.example.com/device                |
|                                               |
|  And enter the code:                          |
|  TXBBPHDZ                                     |
|                                               |
+-----------------------------------------------+

Another example below shows that the client encodes the value of “verification_uri_complete”, which is included in the device authorization response as well, into QR code and asks the user to scan it  (based on an example in RFC 8628 ).

+-------------------------------------------------+
|                                                 |
|  Scan the QR code or, using     +------------+  |
|  a browser on another device,   |[_]..  . [_]|  |
|  visit:                         | .  ..   . .|  |
|  https://as.example.com/device  | . .  . ....|  |
|                                 |.   . . .   |  |
|  And enter the code:            |[_]. ... .  |  |
|  TXBBPHDZ                       +------------+  |
|                                                 |
+-------------------------------------------------+

Once receiving the user_code from the end user in some way (step #7 in Device Flow Diagram), the “verification URI” of the authorization server forwards the user_code to Authlete’s /device/verification API (step #8, #9 in Device Flow Diagram).

  • Request  (step #8 using curl command)
curl -v -X POST https://us.authlete.com/api/21653835348762/device/verification \
    -H 'Authorization: Bearer V5a40R6********C*******95q4HC0Z-T0YKD9-nR6F' \
    -H 'Content-type: application/json' \
    -d '{"userCode":"TXBBPHDZ"}'
  • Response (step #9)
{
    "type": "deviceVerificationResponse",
    "resultCode": "A224001",
    "resultMessage": "[A224001] The user code is valid.",
    "action": "VALID",
    "claimNames": [
        ...
    ],
    "clientId": ...,
    "clientName": "Demo Client",
    "scopes": [
        {
            "defaultEntry": false,
            "name": "openid"
        },
        {
            "defaultEntry": false,
            "name": "profile"
        },
        {
            "defaultEntry": false,
            "name": "read"
        }
    ],
    ...
}

This response states that the verification in terms of the user_code was successful. It also includes other details about the client, requested scopes and/or claims etc.

The authorization server will employ these information to ask consent to the end user.

Completing the verification

The authorization server may authenticate the end user, and present the information of the client and details of the requested access based on the result described above (step #10, #11 in Device Flow Diagram).

Then the server determines the end user’s identifier and properties (e.g. scopes, claims) of the token to be issued, and makes a request to /device/complete API (step #12, #13 in Device Flow Diagram).

  • Request  (step #12 using curl command)
curl -v -X POST https://us.authlete.com/api/21653835348762/device/complete \
  -H 'Authorization: Bearer V5a40R6********C*******95q4HC0Z-T0YKD9-nR6F' \
  -H 'Content-type: application/json'
  -d '{"userCode":"TXBBPHDZ",
       "result":"AUTHORIZED",
       "subject":"testuser01"}'
  • Response (step #13)
{
    "type": "deviceCompleteResponse",
    "resultCode": "A241001",
    "resultMessage": "[A241001] The API call was processed successfully.",
    "action": "SUCCESS"
}

On receiving the response above, The authorization server notifies the end user that the verification process is completed (step #14 in Device Flow Diagram).

Token request and response

As described before, the client makes “device access token requests” using the value of “device_code” to the authorization server (step #a in Device Flow Diagram). It usually sends the requests multiple times (i.e. polling) until the authorization server completes the verification of the user_code and provides an access token.

  • Request (step #b using curl command)
curl -v -X POST https://us.authlete.com/api/21653835348762/auth/token  \
  -H 'Authorization: Bearer V5a40R6********C*******95q4HC0Z-T0YKD9-nR6F' \
  -H 'Content-type: application/json'
  -d '{"parameters":
         "client_id=...
          &grant_type=urn:ietf:params:oauth:grant-type:device_code
          &device_code=-jxwQ_7MEdR3SqS86bEg1ONUYdwGmSYjqH8eIBZ1c3U"}'
  • Response (step #c, before the verification of the user_code is completed)
{
  "type": "tokenResponse",
  "resultCode": "A242307",
  "resultMessage":
    "[A242307] The device authorization request has not been authorized yet.",
  "action": "BAD_REQUEST",
  "grantType": "DEVICE_CODE",
  "responseContent":
    "{\"error_description\":
        \"[A242307] The device authorization request has not been authorized yet.\",
      \"error\":\"authorization_pending\",
      \"error_uri\":\"https://docs.authlete.com/#A242307\"}",
...
}
  • Response (step #c, after the verification of the user_code is completed)
{
  "type": "tokenResponse",
  "resultCode": "A242002",
  "resultMessage":
    "[A242002] The token request
     (grant_type=urn:ietf:params:oauth:grant-type:device_code) was processed
     successfully.",
  "accessToken": "ZJHO26vXTC1LIQXm9aYUFnMZd4R599aFA4hLBmH-OlM",
  "action": "OK",
  "clientId": ...,
  "grantType": "DEVICE_CODE",
  "idToken":
    "eyJhbGciOiJIUzI1NiJ9.
     eyJhdF9oYXNoIjoiZkpNOHhuODlTaVNQVnNsMGFLYnBTQSIsInN1YiI6InRlc3R1
     c2VyMDEiLCJhdWQiOiIxNzIwMTA4MzE2NjE2MSIsImlzcyI6Imh0dHBzOi8vYXV0
     aGxldGUuY29tIiwiZXhwIjoxNTk2NjE5OTk2LCJpYXQiOjE1OTY1MzM1OTZ9.
     OYuGqNbombW_DrSHsm9A07LZWa4UWyV_hSiSAQy-CYI",
  "refreshToken": "sliwK3Oa6Pag1c2aGenZALcGZXAP9cIiIu_zjGIdBCI",
  "responseContent":
    "{\"access_token\":\"ZJHO26vXTC1LIQXm9aYUFnMZd4R599aFA4hLBmH-OlM\",
      \"refresh_token\":\"sliwK3Oa6Pag1c2aGenZALcGZXAP9cIiIu_zjGIdBCI\",
      \"scope\":\"openid profile read\",
      \"id_token\":
        \"eyJhbGciOiJIUzI1NiJ9.
          eyJhdF9oYXNoIjoiZkpNOHhuODlTaVNQVnNsMGFLYnBTQSIsInN1YiI6InRlc3R1
          c2VyMDEiLCJhdWQiOiIxNzIwMTA4MzE2NjE2MSIsImlzcyI6Imh0dHBzOi8vYXV0
          aGxldGUuY29tIiwiZXhwIjoxNTk2NjE5OTk2LCJpYXQiOjE1OTY1MzM1OTZ9.
          OYuGqNbombW_DrSHsm9A07LZWa4UWyV_hSiSAQy-CYI\",
     \"token_type\":\"Bearer\",
     \"expires_in\":3600}",
  "scopes": [
    "openid",
    "profile",
    "read"
  ],
  "subject": "testuser01",
...
}

The authorization server extracts the value of “responseContent” and sends it back to the client  (step #d in Device Flow Diagram).

See also