# 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.