OAuth 2.0 Device Authorization Grant Flow Example

The Oauth 2 Device Authorization Grant, also formerly known as the Device Flow, is an Oauth 2 extension that enables devices with no browser or limited input capability to obtain an access token.

For video lessons on how to secure your Spring Boot application with OAuth 2.0. and Spring Security 5, please checkout my complete video course OAuth 2.0. in Spring Boot applications.

You might have experienced the Device flow when authorizing a PlayStation or a TV app to access your Microsoft or Google account.

Because there might be no browser on the device or because it is very inconvenient to type the email address and password using the TV remote control, the device will simply display a message similar to the one below.

OAuth Device Flow. Message on device.

You as a User will then use your computer, tablet, or phone, open the browser window, navigate to https://www.google.com/device, and will see a prompt inviting you to enter the code displayed on the TV screen.

OAuth Device Flow Enter Code Screen

Once you enter the code and continue to the next screen, a standard OAuth Authorization flow will begin.

First, you will need to authenticate.

Enter Password Screen

Once you have successfully signed in, you will be presented with a Consent screen. For this tutorial, I have created a test Google project, so please disregard the project name on the consent screen below.

OAuth 2 Device Code Flow Consent Screen

Once you click on the Allow button and give your consent, the authorization flow will be complete. You can go back to a device screen and continue there.

OAuth 2 Device Authorization Code Grant Flow Success Message

While the user is going through the authorization flow, the app on the device will be polling Google’s authorization server every few seconds to learn if you have authorized it to access the information it needs.

Let’s learn how to request for device code and how to exchange this device code for an access token.

Requesting a Device Code

The client application that runs on a TV device will need to send an HTTP request to an authorization server providing its OAuth Client Id and a Scope.

curl --location --request POST 'https://oauth2.googleapis.com/device/code' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=14181410...' \
--data-urlencode 'scope=https://www.googleapis.com/auth/userinfo.email'

Where:

  • https://oauth2.googleapis.com/device/code – is a URL to Google’s web service endpoint for the OAuth2 Device Authorization Grant flow,
  • client_id –  Before an app on the device can communicate with Google’s OAuth authorization server, a developer of that app will need to create an account with Google’s API console, create a new project, and the for that project create an OAuth Client credentials: ClientId and Client secret. This request needs to include client_id value only,
  • scope – The second parameter is a scope. With this request, a client application will request to have access to the user email address.

In response, the Google authorization server will return the following JSON:

{
"device_code": "AH-1Ng0oneWhefC6un25JN8v6vG9__TRoR3pLBySTGzgL6dib7AHsF7rnIDb3FiBfVbM_2Hf9E9gM54IPWN0iIN3BtIH9AsATg",
"user_code": "GQSV-SBMX",
"expires_in": 1800,
"interval": 5,
"verification_url": "https://www.google.com/device"
}

Where:

  • device_code –  Is a value that a client application will need to include in its request to the authorization server when polling every 5 seconds to learn if the user has granted their consent,
  • user_code – the Code that user will need to enter on their computer, tablet or phone,
  • interval – Time interval in seconds, how often the client application on the device will poll google’s authorization server to learn if the user has used this code and has granted their consent,
  • verification_url – Is the URL the user will need to navigate to on their computer, tablet, or phone to enter the code.

Polling for Access Token

While waiting for a user to use the Device Code, the client application will communicate with the authorization server every few seconds by sending the following HTTP request. If the user has used their code and has granted their consent, the authorization server will respond back with an access token.

curl --location --request POST 'https://oauth2.googleapis.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=14181410....' \
--data-urlencode 'client_secret=PFlGtuX....' \
--data-urlencode 'device_code=AH-1Ng2Hd1n67rQM-cTXGBC3JUpAwxA-M5O2v3ACP7qx8q5JTeB9_xtygbMNJ3ksWDcg_aHnB-lWeSMXpeP1wxBqRD45XJzdbA' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code'

Where:

  • client_id and client_secret – are OAuth 2.0 client credentials,
  • device_code – is a value received in the response for Device Code. Do not confuse this value with a user_code,
  • grant_type – is a static value for the Device Authorization Grant Flow. This value does not change.

Once user consent has been received, the authorization code will respond with a JSON containing an access token.

{
"access_token": "ya29.a0AfH6SMAL1m5lq……..",
"expires_in": 3599,
"refresh_token": "1//05rNY…….",
"scope": "https://www.googleapis.com/auth/userinfo.email",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsImtp……."
}

If the user has not yet granted their consent, the authorization server will respond with the authorization_pending error message:

{
  "error": "authorization_pending",
  "error_description": "Precondition Required"
}

If the client application polls the authorization server too frequently, the authorization server will respond with a slow_down error message.

{
"error": "slow_down",
"error_description": "Forbidden"
}

I hope this tutorial was of some help to you. If there are interested to learn how to implement other OAuth 2.0 authorization flows, have a look at OAuth 2.0 authorization flows tutorials.

Happy learning!

Leave a Reply

Your email address will not be published. Required fields are marked *