AuthServer

This class provides authorization server activity.

class DIRAC.FrameworkSystem.private.authorization.AuthServer.AuthServer

Bases: AuthorizationServer

Implementation of the authlib.oauth2.rfc6749.AuthorizationServer.

This framework has been changed and simplified to be used for DIRAC purposes, namely authorization on the third party side and saving the received extended long-term access tokens on the DIRAC side with the possibility of their future use on behalf of the user without his participation.

The idea is that DIRAC itself is not an identity provider and relies on third-party resources such as EGI Checkin or WLCG IAM.

Initialize:

server = AuthServer()
LOCATION = None
__init__()
authenticate_client(request, methods, endpoint='token')

Authenticate client via HTTP request information with the given methods, such as client_secret_basic, client_secret_post.

create_authorization_response(response, username)

Rewrite original Authlib method authlib.authlib.oauth2.rfc6749.authorization_server.create_authorization_response to catch errors and remove authorization session.

Returns:

TornadoResponse object

create_endpoint_response(name, request=None)

Validate endpoint request and create endpoint response.

Parameters:
  • name – Endpoint name

  • request – HTTP request instance.

Returns:

Response

create_json_request(request)

Parse request. Rewrite authlib method.

create_oauth2_request(request, method_cls=<class 'DIRAC.FrameworkSystem.private.authorization.utils.Requests.OAuth2Request'>, use_json=False)

Parse request. Rewrite authlib method.

create_token_response(request=None)

Validate token request and create token response.

Parameters:

request – HTTP request instance

generateProxyOrToken(client, grant_type, user=None, scope=None, expires_in=None, include_refresh_token=True)

Generate proxy or tokens after authorization

Parameters:
  • client – instance of the IdP client

  • grant_type – authorization grant type (unused)

  • user (str) – user identifier

  • scope (str) – requested scope

  • expires_in – when the token should expire (unused)

  • include_refresh_token (bool) – to include refresh token (unused)

Returns:

dict or str – will return tokens as dict or proxy as string

generate_token(grant_type, client, user=None, scope=None, expires_in=None, include_refresh_token=True)

Generate the token dict.

Parameters:
  • grant_type – current requested grant_type.

  • client – the client that making the request.

  • user – current authorized user.

  • expires_in – if provided, use this value as expires_in.

  • scope – current requested scope.

  • include_refresh_token – should refresh_token be included.

Returns:

Token dict

getIdPAuthorization(provider, request)

Submit subsession to authorize with chosen provider and return dict with authorization url and session number

Parameters:
  • provider (str) – provider name

  • request (object) – main session request

Returns:

S_OK(response)/S_ERROR() – dictionary contain response generated by handle_response

get_authorization_grant(request)

Find the authorization grant for current request.

Parameters:

request – OAuth2Request instance.

Returns:

grant instance

Validate current HTTP request for authorization page. This page is designed for resource owner to grant or deny the authorization.

get_error_uri(request, error)

Return a URI for the given error, framework may implement this method.

get_token_grant(request)

Find the token grant for current request.

Parameters:

request – OAuth2Request instance.

Returns:

grant instance

handle_error_response(request, error)
handle_response(status_code=None, payload=None, headers=None, newSession=None, delSession=None)

Handle response

Parameters:
  • status_code (int) – http status code

  • payload – response payload

  • headers (list) – headers

  • newSession (dict) – session data to store

Returns:

TornadoResponse()

parseIdPAuthorizationResponse(response, session)

Fill session by user profile, tokens, comment, OIDC authorize status, etc. Prepare dict with user parameters, if DN is absent there try to get it. Create new or modify existing DIRAC user and store the session

Parameters:
  • response (dict) – authorization response

  • session (str) – session

Returns:

S_OK(dict)/S_ERROR()

query_client(client_id)

Search authorization client.

Parameters:

clientID (str) – client ID

Returns:

client as object or None

readToken(token)

Decode self token

Parameters:

token (str) – token to decode

Returns:

S_OK(dict)/S_ERROR()

registerRefreshToken(payload, token)

Register refresh token to protect it from reuse

Parameters:
  • payload (dict) – payload

  • token (dict) – token as a dictionary

Returns:

S_OK(dict)S_ERROR()

register_client_auth_method(method, func)

Add more client auth method. The default methods are:

  • none: The client is a public client and does not have a client secret

  • client_secret_post: The client uses the HTTP POST parameters

  • client_secret_basic: The client uses HTTP Basic

Parameters:
  • method – Name of the Auth method

  • func – Function to authenticate the client

The auth method accept two parameters: query_client and request, an example for this method:

def authenticate_client_via_custom(query_client, request):
    client_id = request.headers['X-Client-Id']
    client = query_client(client_id)
    do_some_validation(client)
    return client

authorization_server.register_client_auth_method(
    'custom', authenticate_client_via_custom)
register_endpoint(endpoint)

Add extra endpoint to authorization server. e.g. RevocationEndpoint:

authorization_server.register_endpoint(RevocationEndpoint)
Parameters:

endpoint_cls – A endpoint class or instance.

register_grant(grant_cls, extensions=None)

Register a grant class into the endpoint registry. Developers can implement the grants in authlib.oauth2.rfc6749.grants and register with this method:

class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
    def authenticate_user(self, credential):
        # ...

authorization_server.register_grant(AuthorizationCodeGrant)
Parameters:
  • grant_cls – a grant class.

  • extensions – extensions for the grant class.

register_token_generator(grant_type, func)

Register a function as token generator for the given grant_type. Developers MUST register a default token generator with a special grant_type=default:

def generate_bearer_token(grant_type, client, user=None, scope=None,
                          expires_in=None, include_refresh_token=True):
    token = {'token_type': 'Bearer', 'access_token': ...}
    if include_refresh_token:
        token['refresh_token'] = ...
    ...
    return token

authorization_server.register_token_generator('default', generate_bearer_token)

If you register a generator for a certain grant type, that generator will only works for the given grant type:

authorization_server.register_token_generator('client_credentials', generate_bearer_token)
Parameters:
  • grant_type – string name of the grant type

  • func – a function to generate token

save_token(token, request)

Define function to save the generated token into database.

send_signal(name, *args, **kwargs)

Framework integration can re-implement this method to support signal system.

validateIdentityProvider(request, provider)

Check if identity provider registered in DIRAC

Parameters:
  • request (object) – request

  • provider (str) – provider name

Returns:

OAuth2Request object or HTML – new request with provider name or provider selector

Validate current HTTP request for authorization page. This page is designed for resource owner to grant or deny the authorization:

:param object request: tornado request
:param provider: provider
Returns:

response generated by handle_response or S_ERROR or html

validate_requested_scope(scope, state=None)

See authlib.oauth2.rfc6749.authorization_server.validate_requested_scope()