RFC7592: OAuth 2.0 Dynamic Client Registration Management Protocol

This section contains the generic implementation of RFC7592. OAuth 2.0 Dynamic Client Registration Management Protocol allows developers edit and delete OAuth client via API through Authorization Server. This specification is an extension of RFC7591: OAuth 2.0 Dynamic Client Registration Protocol.

Client Configuration Endpoint

Before register the endpoint, developers MUST implement the missing methods:

from authlib.oauth2.rfc7592 import ClientConfigurationEndpoint


class MyClientConfigurationEndpoint(ClientConfigurationEndpoint):
    def authenticate_token(self, request):
        # this method is used to authenticate the registration access
        # token returned by the RFC7591 registration endpoint
        auth_header = request.headers.get('Authorization')
        bearer_token = auth_header.split()[1]
        token = Token.get(bearer_token)
        return token

    def authenticate_client(self, request):
        client_id = request.data.get('client_id')
        return Client.get(client_id=client_id)

    def revoke_access_token(self, token, request):
        token.revoked = True
        token.save()

    def check_permission(self, client, request):
        return client.editable

    def delete_client(self, client, request):
        client.delete()

    def save_client(self, client_info, client_metadata, request):
        client = OAuthClient(
            user_id=request.credential.user_id,
            client_id=client_info['client_id'],
            client_secret=client_info['client_secret'],
            **client_metadata,
        )
        client.save()
        return client

    def generate_client_registration_info(self, client, request):
        access_token = request.headers['Authorization'].split(' ')[1]
        return {
            'registration_client_uri': request.uri,
            'registration_access_token': access_token,
        }

    def get_server_metadata(self):
        return {
            'issuer': ...,
            'authorization_endpoint': ...,
            'token_endpoint': ...,
            'jwks_uri': ...,
            'registration_endpoint': ...,
            'scopes_supported': ...,
            'response_types_supported': ...,
            'response_modes_supported': ...,
            'grant_types_supported': ...,
            'token_endpoint_auth_methods_supported': ...,
            'token_endpoint_auth_signing_alg_values_supported': ...,
            'service_documentation': ...,
            'ui_locales_supported': ...,
            'op_policy_uri': ...,
            'op_tos_uri': ...,
            'revocation_endpoint': ...,
            'revocation_endpoint_auth_methods_supported': ...,
            'revocation_endpoint_auth_signing_alg_values_supported': ...,
            'introspection_endpoint': ...,
            'introspection_endpoint_auth_methods_supported': ...,
            'introspection_endpoint_auth_signing_alg_values_supported': ...,
            'code_challenge_methods_supported': ...,
        }

API Reference

class authlib.oauth2.rfc7592.ClientConfigurationEndpoint(server)
claims_class

alias of ClientMetadataClaims

generate_client_registration_info(client, request)

Generate `registration_client_uri and registration_access_token for RFC7592. By default this method returns the values sent in the current request. Developers MUST rewrite this method to return different registration information.:

def generate_client_registration_info(self, client, request):{
    access_token = request.headers['Authorization'].split(' ')[1]
    return {
        'registration_client_uri': request.uri,
        'registration_access_token': access_token,
    }
Parameters:
  • client – the instance of OAuth client

  • request – formatted request instance

authenticate_token(request)

Authenticate current credential who is requesting to register a client. Developers MUST implement this method in subclass:

def authenticate_token(self, request):
    auth = request.headers.get('Authorization')
    return get_token_by_auth(auth)
Returns:

token instance

authenticate_client(request)

Read a client from the request payload. Developers MUST implement this method in subclass:

def authenticate_client(self, request):
    client_id = request.data.get('client_id')
    return Client.get(client_id=client_id)
Returns:

client instance

revoke_access_token(token, request)

Revoke a token access in case an invalid client has been requested. Developers MUST implement this method in subclass:

def revoke_access_token(self, token, request):
    token.revoked = True
    token.save()
check_permission(client, request)

Checks wether the current client is allowed to be accessed, edited or deleted. Developers MUST implement it in subclass, e.g.:

def check_permission(self, client, request):
    return client.editable
Returns:

boolean

delete_client(client, request)

Delete authorization code from database or cache. Developers MUST implement it in subclass, e.g.:

def delete_client(self, client, request):
    client.delete()
Parameters:
  • client – the instance of OAuth client

  • request – formatted request instance

update_client(client, client_metadata, request)

Update the client in the database. Developers MUST implement this method in subclass:

def update_client(self, client, client_metadata, request):
    client.set_client_metadata({**client.client_metadata, **client_metadata})
    client.save()
    return client
Parameters:
  • client – the instance of OAuth client

  • client_metadata – a dict of the client claims to update

  • request – formatted request instance

Returns:

client instance

get_server_metadata()

Return server metadata which includes supported grant types, response types and etc.