DeviceFlow

class DIRAC.FrameworkSystem.private.authorization.grants.DeviceFlow.DeviceAuthorizationEndpoint(server)

Bases: DeviceAuthorizationEndpoint

See authlib.oauth2.rfc8628.DeviceAuthorizationEndpoint

CLIENT_AUTH_METHODS = ['client_secret_basic', 'client_secret_post', 'none']
ENDPOINT_NAME = 'device_authorization'
EXPIRES_IN = 1800

The lifetime in seconds of the “device_code” and “user_code”

INTERVAL = 5

The minimum amount of time in seconds that the client SHOULD wait between polling requests to the token endpoint.

USER_CODE_TYPE = 'string'

customize “user_code” type, string or digital

__init__(server)
authenticate_client(request)

client_id is REQUIRED if the client is not authenticating with the authorization server as described in Section 3.2.1. of [RFC6749].

This means the endpoint support “none” authentication method. In this case, this endpoint’s auth methods are:

  • client_secret_basic

  • client_secret_post

  • none

Developers change the value of CLIENT_AUTH_METHODS in subclass. For instance:

class MyDeviceAuthorizationEndpoint(DeviceAuthorizationEndpoint):
    # only support ``client_secret_basic`` auth method
    CLIENT_AUTH_METHODS = ['client_secret_basic']
create_endpoint_request(request)
create_endpoint_response(req)

See authlib.oauth2.rfc8628.DeviceAuthorizationEndpoint.create_endpoint_response()

generate_device_code()

A method to generate device_code value for device authorization endpoint. This method will generate a random string of 42 characters. Developers can rewrite this method to create their own device_code.

generate_user_code()

A method to generate user_code value for device authorization endpoint. This method will generate a random string like MQNA-JPOZ. Developers can rewrite this method to create their own user_code.

get_verification_uri()

Create verification uri when DeviceCode flow initialized

Returns:

str

save_device_credential(client_id, scope, data)

Save device credentials

Parameters:
  • client_id (str) – client id

  • scope (str) – request scopes

  • data (dict) – device credentials

class DIRAC.FrameworkSystem.private.authorization.grants.DeviceFlow.DeviceCodeGrant(request: OAuth2Request, server)

Bases: DeviceCodeGrant, AuthorizationEndpointMixin

See authlib.oauth2.rfc8628.DeviceCodeGrant

ERROR_RESPONSE_FRAGMENT = False
GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code'

Designed for which “grant_type”

RESPONSE_TYPES = {'device'}
TOKEN_ENDPOINT_AUTH_METHODS = ['client_secret_basic', 'client_secret_post', 'none']

Allowed client auth methods for token endpoint

TOKEN_ENDPOINT_HTTP_METHODS = ['POST']

Allowed HTTP methods of this token endpoint

TOKEN_RESPONSE_HEADER = [('Content-Type', 'application/json'), ('Cache-Control', 'no-store'), ('Pragma', 'no-cache')]
__init__(request: OAuth2Request, server)
authenticate_token_endpoint_client()

Authenticate client with the given methods for token endpoint.

For example, the client makes the following HTTP request using TLS:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

Default available methods are: “none”, “client_secret_basic” and “client_secret_post”.

Returns:

client

classmethod check_authorization_endpoint(request: OAuth2Request)
classmethod check_token_endpoint(request: OAuth2Request)
property client
create_authorization_response(redirect_uri, user)

Mark session as authed with received user

Parameters:
  • redirect_uri (str) – redirect uri

  • user (dict) – dictionary with username and userID

Returns:

result of handle_response

create_token_response()

If the access token request is valid and authorized, the authorization server issues an access token and optional refresh token.

execute_hook(hook_type, *args, **kwargs)
generate_token(user=None, scope=None, grant_type=None, expires_in=None, include_refresh_token=True)
query_device_credential(device_code)

Get device credential from previously savings via DeviceAuthorizationEndpoint.

Parameters:

device_code (str) – device code

Returns:

dict

query_user_grant(user_code)

Check if user alredy authed and return it to token generator

Parameters:

user_code (str) – user code

Returns:

(str, bool) or None – user dict and user auth status

register_hook(hook_type, hook)
save_token(token)

A method to save token into database.

should_slow_down(*args)

The authorization request is still pending and polling should continue, but the interval MUST be increased by 5 seconds for this and all subsequent requests.

static validate_authorization_redirect_uri(request: OAuth2Request, client)
validate_authorization_request()

Validate authorization request

Returns:

None

validate_device_credential(credential)
validate_requested_scope()

Validate if requested scope is supported by Authorization Server.

validate_token_request()

After displaying instructions to the user, the client creates an access token request and sends it to the token endpoint with the following parameters:

grant_type

REQUIRED. Value MUST be set to “urn:ietf:params:oauth:grant-type:device_code”.

device_code

REQUIRED. The device verification code, “device_code” from the device authorization response.

client_id

REQUIRED if the client is not authenticating with the authorization server as described in Section 3.2.1. of [RFC6749]. The client identifier as described in Section 2.2 of [RFC6749].

For example, the client makes the following HTTPS request:

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS
&client_id=1406020730