Connect device applications (device authorization grant flow)

When you have a device application that has a limited user interface and is not capable of using a web browser for user authentication, use the device authorization grant flow.

The end user logs in and authorizes the device using a browser on another device. The authentication process involves providing the end user with a verification code, which they enter to complete the authentication.

A common use case is that the device displays a QR code with a URL that includes the verification code. The end user scans the code using their mobile device, which opens a web browser where the end user can log in. In this case, the verification code is automatically entered for them.

Before you start

Define an OIDC connection for the client application in 10Duke SysAdmin.

  • This includes defining the client ID (OAuth client_id) for your client application and the authentication flow used.

  • You also set when access tokens (and user sessions) in this client application expire. You would usually use the “detached” session attachment with this authentication flow: the user typically signs out immediately after authenticating, and the “attached” setting would revoke the access token right away.

Step 1: Initiate authentication flow

Initiate the authentication flow from the client application by sending a POST request to the 10Duke Enterprise device authentication/authorization endpoint.

An example request (line breaks added for display purposes):

POST /user/oauth20/device-authz
   Content-type: application/x-www-form-urlencoded

   scope=openid+profile+email
   &client_id=79w1-6s41-4s7x-8e96-76u986gs1

Set the content header to Content-Type: application/x-www-form-urlencoded.

In the form data (the request body), provide an actual value in client_id, and in scope, provide the requested OAuth scopes. This must contain at least openid.

Step 2: Instruct user to verify the authentication

A successful call should return a response with a JSON payload that looks like this:

{
   "user_code": "TPVM-TVVB",
   "device_code": "9paosark52gakl6nssbs0m6gbf5qh1gr7kkhtv2gujvvt8dpni4q",
   "verification_uri_complete": "https://customer.10duke.net/user/device?userCode=TPVM-TVVB",
   "verification_uri": "https://customer.10duke.net/user/device",
   "expires_in": 299
}

Handle the response in the client application. Extract the two verification codes from the response: user_code that the end user must enter on the verification page and device_code that your client application uses to get an access token.

verification_uri contains the URL of the verification page in your 10Duke Enterprise deployment. Your client application must somehow instruct the user to browse to this URL, where they first log in and then enter the user code to complete the authentication process. How you instruct the user depends on the capabilities of the device. The user must complete the authentication within the time given in expires_in.

Optionally, you can also provide the user with the direct URL from verification_uri_complete, for example, as a QR code. This URL enters the user code automatically after the user has logged in. We recommend that you still also show the verification URL and user code separately as text, because the short URL is easier to type manually if needed.

Optional parameters that you can use in the URLs:

  • If the user is not logged in yet, by default the login page is opened for them. With flow=register, you can request to open the registration page instead.

  • Provide the user’s email address with the login_hint parameter, which enables 10Duke Enterprise to automatically populate the email address field so the user doesn’t have to fill it in again.

Step 3: Get an access token

While waiting for the end user to complete the authentication process, start polling the access token endpoint every 5 seconds from the client application.

An example request (line breaks added for display purposes):

POST /user/oauth20/token
   Content-type: application/x-www-form-urlencoded

   grant_type=urn:ietf:params:oauth:grant-type:device_code
   &device_code=9paosark52gakl6nssbs0m6gbf5qh1gr7kkhtv2gujvvt8dpni4q
   &client_id=79w1-6s41-4s7x-8e96-76u986gs1

Set the content header to Content-Type: application/x-www-form-urlencoded.

In the form data (the request body), use grant_type=urn:ietf:params:oauth:grant-type:device_code, provide the device code you got in the earlier response in device_code, and provide the client ID in client_id.

When the end user has successfully authenticated, 10Duke Enterprise returns a response like this:

{
   "access_token": "ACCESS_TOKEN_VALUE",
   "remember":false,
   "refresh_token": "REFRESH_TOKEN_VALUE",
   "scope":"openid profile email"
   "id_token": "ID_TOKEN_VALUE",
   "token_type": "Bearer",
   "expires_in": 3600,
   "issued_at":1675702153
   "refresh_token_expires_in":86400
}

Your client application can use access_token to authorize 10Duke API requests, refresh_token (if granted and included in the response) for requesting new access tokens, and id_token to read user details. refresh_token_expires_in contains the seconds until the OAuth session expires, after which the client application can no longer refresh the access token.

The response fields may vary depending on the 10Duke Enterprise release. Make sure your client application is able to handle the response if new fields are added. The response can also contain additional fields depending on possible customizations.

Error responses:

  • If the authentication hasn’t been completed yet, 10Duke Enterprise returns a JSON response like this:

    {
       "error": "authorization_pending",
       "error_description": "Waiting for end user to complete authorization"
    }
    

    Wait for 5 seconds and send a request again.

  • If the end user doesn’t complete the authentication in time and the login session expires, 10Duke Enterprise returns a JSON response like this:

    {
       "error": "expired_token",
       "error_description": "Expired device_code"
    }
    

    Initiate a new authentication flow.

Next steps

After a successful authentication, your client application can: