Device code flow in Keycloak
Some devices do not have access to a web browser or a user input interface where to easily enter credentials. This includes smart TVs, or just console applications on servers where you can not load a web browser.
The device shows a code (“user_code”) which corresponds to a “login process”. The user has to copy this code, then a standard login process starts. The device polls an endpoint, the endpoint returns a token when the user completes the login process.
Take a look at your “open id endpoint configuration” (akka “well known”), there is 1 new endpoint :
And a new grant type :
- urn:ietf:params:oauth:grant-type:device_code
You also have to use the /token endpoint.
Create a new confidential client and enable “OAuth 2.0 Device Authorization Grant Enabled” :
The client has to be a confidential client.
use the new “device” endpoint in a POST request with :
- client_id
- client_secret
This will generate a combo :
- device_code : a confidential code, where to poll the token
- user_code : an “authentication process id”
- verification_uri : where to redirect the user to the authentication process
- verification_uri_complete : the same, with the user_code in URI. Encode this in a QRCode.
- expires_in
- interval : for polling
curl --location --request POST 'https://app.please-open.it/auth/realms/--realmid--/protocol/openid-connect/auth/device' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=--client_id--' \
--data-urlencode 'client_secret=--client_secret--'
Open the “verification URI”, the “device” endpoint in the browser. It prompts for a user_code.
Or directly provide the code in the URL, with the “verification_uri_complete”.
Then the authentication process starts.
Using the /token endpoint, poll for a token with the new device code grant type. The link with the previous step is done with the “device_code” returned previously :
curl --location --request POST 'https://app.please-open.it/auth/realms/--realmid--/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'device_code=--device_code--' \
--data-urlencode 'client_id=--client_id--' \
--data-urlencode 'client_secret=--client_secret--' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code'
The endpoint returns :
{
"error": "authorization_pending",
"error_description": "The authorization request is still pending"
}
When the user has finished the authentication process, it returns a standard access_token/refresh_token structure as usual.
That’s it !