From some times now (release 13.0) Keycloak supports device code flow which can be very usefull in some cases. The device code flow is an OAuth 2.0 authorization flow used by applications that cannot securely store a client secret, such as applications installed on devices like TVs, interactive voice response systems, and printers. This flow is used to obtain an access token that can then be used to access a protected resource. In Keycloak, the device code flow works by the user entering a code displayed on their device into a web browser to authenticate with Keycloak. Once authenticated, Keycloak will return an access token that can be used to access the protected resource.
What is device code flow ?
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.
Endpoints
Take a look at your « open id endpoint configuration » (akka « well known »), there is 1 new endpoint :
- https://app.please-open.it/auth/realms/–realmid–/protocol/openid-connect/auth/device
And a new grant type :
- urn:ietf:params:oauth:grant-type:device_code
You also have to use the /token endpoint.
Client
Create a new confidential client and enable « OAuth 2.0 Device Authorization Grant Enabled » :
The client has to be a confidential client.
Generate a user code
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--'
Authenticate
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.
Get a token : polling
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 !
- Keycloak roles restriction and full scopes - 10 décembre 2024
- How to enrich native metrics in KeyCloak - 21 août 2024
- Keycloak Authenticator explained - 7 mars 2024