From 941aab0af5de88d16f4417a7d7c1bedebd8e2ccf Mon Sep 17 00:00:00 2001 From: manonmichel Date: Mon, 5 Jun 2023 14:03:29 +0200 Subject: [PATCH] feat: Add device authorization grant --- src/keycloak/keycloak_openid.py | 23 +++++++++++++++++++++++ src/keycloak/urls_patterns.py | 1 + 2 files changed, 24 insertions(+) diff --git a/src/keycloak/keycloak_openid.py b/src/keycloak/keycloak_openid.py index f689c37..58ca1b8 100644 --- a/src/keycloak/keycloak_openid.py +++ b/src/keycloak/keycloak_openid.py @@ -711,3 +711,26 @@ class KeycloakOpenID: URL_CLIENT_REGISTRATION.format(**params_path), data=json.dumps(payload) ) return raise_error_from_response(data_raw, KeycloakPostError) + + def device(self): + """Get device authorization grant. + + The device endpoint is used to obtain a user code verification and user authentication. + The response contains a device_code, user_code, verification_uri, verification_uri_complete, + expires_in (lifetime in seconds for device_code and user_code), and polling interval. + Users can either follow the verification_uri and enter the user_code or follow the verification_uri_complete. + After authenticating with valid credentials, users can obtain tokens using the + "urn:ietf:params:oauth:grant-type:device_code" grant_type and the device_code. + + https://auth0.com/docs/get-started/authentication-and-authorization-flow/device-authorization-flow + https://github.com/keycloak/keycloak-community/blob/main/design/oauth2-device-authorization-grant.md#how-to-try-it + + """ + params_path = {"realm-name": self.realm_name} + payload = { + "client_id": self.client_id, + } + + payload = self._add_secret_key(payload) + data_raw = self.connection.raw_post(URL_DEVICE.format(**params_path), data=payload) + return raise_error_from_response(data_raw, KeycloakPostError) diff --git a/src/keycloak/urls_patterns.py b/src/keycloak/urls_patterns.py index aa01732..679d973 100644 --- a/src/keycloak/urls_patterns.py +++ b/src/keycloak/urls_patterns.py @@ -37,6 +37,7 @@ URL_AUTH = ( "{authorization-endpoint}?client_id={client-id}&response_type=code&redirect_uri={redirect-uri}" "&scope={scope}&state={state}" ) +URL_DEVICE = "realms/{realm-name}/protocol/openid-connect/auth/device" URL_CLIENT_REGISTRATION = URL_REALM + "/clients-registrations/default" URL_CLIENT_UPDATE = URL_CLIENT_REGISTRATION + "/{client-id}"