OAuth 2.0 - Device flow
Overview
The device flow is designed for devices that either do not have access to a browser or have limited input capabilities. This flow allows users to share specific data with an application while keeping their usernames, passwords, and other information private.
This grant type eliminates the need for the client to store user credentials for future use by exchanging them for a long-lived access token or refresh token.
How to implement the device flow
The client's grant type property is set appropriately
The grant_type property must be set to urn:ietf:params:oauth:grant-type:device_code
Register the OAuth20/OIDC application in Identify
From the Safewhere Admin application list, you can create an OAuth 2.0 application, then open its sub tabs and update the following:
- On its connection tab:
- Client ID: Specifies the unique ID of the application. Client ID is case-sensitive.
- Client secret: Specifies the Client secret of the application. Client secret is case-sensitive.
- Token endpoint authentication method: Specifies the client authentication method to the token endpoint.
- Allowed Callback URIs: Specifies the redirect URL after successful authentication, e.g https://#identifydomain/runtime/oauth2/devicepairingcallback
- Application name: Specifies the name of the application
- Security token audiences: Specifies the recipients (usually in URI format) that issued access tokens are intended for. When the resource parameter is missing, an access token is issued with its 'aud' claim set to all configured audiences.
- On its security tab:
- JWS algorithm: Either RSASigning or HMACSymmetric.
- Symmetric signing key: Used to generate a HMAC Symmetric signing key; key can be 32-byte, 48-byte, or 64-byte. You can then either copy the key and paste it to the configuration or check the appropriate check box and click Select key to apply it.
- Allow device pairing flow: This setting must be True.
- Code life time (minutes): Specifies the input code lifetime. Its default value is 60.
- Number of user code group: Specifies the number of 4-character groups of a code. Its default value is 2.
Here is the screenshot of a sample connection:
Ask for a token
The flow proceeds as follows:
- The device client requests access from Identify, including its client identifier in the request.
- Identify issues a verification code and an end-user code and provides the end-user verification URI to the device client.
- The device client instructs the end-user to use their browser (typically on a laptop or mobile phone) to visit the provided verification URI. The client also provides the end-user with the code needed to grant access.
- Identify authenticates the end-user and prompts them to grant the client's access request. If the user is not logged in, they will be required to log in first.
- During the user interaction, the device client continuously sends POST requests to the Identify token endpoint to check if the end-user has completed the authorization step.
- Once the end-user grants access, Identify validates the verification code provided by the client and responds with an access token.
Step 1: Request device and user code
Perform a POST operation to the device pairing endpoint:
https://#identifydomain/runtime/oauth2/device_authorization
URI parameters:
Parameter | Description |
---|---|
client_id | Your application's client ID |
scope | Optional. A space-delimited list of scopes that identifies the resources that your application could access on the user's behalf |
Step 2: Handle the Identify response
The authorization server returns a JSON object to your device.
{
"device_code": "wUEcJfy49qKjP6...28j5iZszQ==",
"user_code": "e9fPOw==-1O6hjg==",
"verification_uri": "https://identify01.identify.safewhere.com/runtime/oauth2/devicepairing",
"verification_uri_complete": "https://identify01.identify.safewhere.com/runtime/oauth2/devicepairing?user_code=e9fPOw%3d%3d-1O6hjg%3d%3d"
}
Its content includes:
- device_code: The device verification code.
- user_code: The device verification code.
- verification_uri: The end-user verification URI on the authorization server
- verification_uri_complete: The end-user verification URI on the authorization server with its user_code
Step 3: User login
- The user navigates to the code verification endpoint displayed by the
verification_uri
orverification_uri_complete
parameter:
- The user enters the verification code.
- If the code is correct and the user is not logged in, they will be prompted to log in.
- The user finishes authentication.
Step 4: Poll for the Identify token
During user interaction, the device client continuously sends POST requests to the Identify token endpoint
https://#identifydomain/runtime/oauth2/token.idp
URI parameters:
Parameter | Description |
---|---|
client_id | Your application's Client ID. |
grant_type | This must be "urn:ietf:params:oauth:grant-type:device_code". |
device_code | This comes from the message which is received at the 2nd step. |
Step 5: Get the access token
Successful response
If the user has approved the grant, the token endpoint responds with a successful response
{
"scope": "identify*scim",
"token_type": "Bearer",
"access_token": "eyJhbGciO...moscLx8qwlg",
"expires_in": 3600
}
If you decode the access_token, you will see that it contains the following claims:
{
"uiId": "u+oU2DHIaB5wq2I8EUG80A==",
"unique_name": "admin",
"sub": "admin",
"urn:identify:rest-api:role": "helloAngel",
"name": "admin",
"urn:internal:userid": "e63e2d48-2b6a-4f4d-b3c1-2a5b8814217a",
"client_id": "client_device_pairing_id",
"token_usage": "access_token",
"jti": "05f25219-0194-4813-8631-a60579368af6",
"scope": "identify*scim",
"aud": "https://identify01.identify.safewhere.com/runtime/",
"azp": "client_device_pairing_id",
"iat": 1735378514,
"nbf": 1735378514,
"exp": 1735382114,
"iss": "https://identify01.identify.safewhere.com/runtime/oauth2"
}
Error response
If the device authorization grant is still pending or the device code is invalid for any reason, Identify responds with an error response to the client.
{
"error": "invalid_request",
"error_description": "..."
}