# RFC7591: OAuth 2.0 Dynamic Client Registration Protocol

This section contains the generic implementation of RFC7591. OAuth 2.0 Dynamic Client Registration Protocol allows developers creating OAuth client via API through Authorization Server.

To integrate with Authlib Flask OAuth 2.0 Server or Django OAuth 2.0 Server, developers MUST implement the missing methods of `ClientRegistrationEndpoint`.

## Client Registration Endpoint

The client registration endpoint accepts client metadata as JSON payload via POST request. The metadata may contain a JWT `software_statement` value. Endpoint can choose if it support `software_statement`, it is not enabled by default.

Changed in version v0.15: ClientRegistrationEndpoint has a breaking change in v0.15. Method of `authenticate_user` is replaced by `authenticate_token`, and parameters in `save_client` is also changed.

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

    from authlib.oauth2.rfc7591 import ClientRegistrationEndpoint

    class MyClientRegistrationEndpoint(ClientRegistrationEndpoint):
        def authenticate_token(self, request):
            # this method is used to find who is going to create the client
            auth_header = request.headers.get('Authorization')
            # bearer a-token-string
            bearer_token = auth_header.split()[1]
            token = Token.query.get(bearer_token)
            return token

        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):
            return {
                'registration_client_uri': url_for("client_management_endpoint", client_id=client.client_id),
                'registration_access_token': create_management_access_token_for_client(client),
            }

If developers want to support `software_statement`, additional methods should be implemented:

    class MyClientRegistrationEndpoint(ClientRegistrationEndpoint):
        # adding this to support JWT with RS256 alg, you may change it to other alg values
        software_statement_alg_values_supported = ['RS256']

        def resolve_public_key(self, request):
            # the authenticated user's public key
            # can be a string, bytes, jwk and jwk set
            return request.user.public_jwk_set

Register this endpoint and use this endpoint in routes:

    authorization_server.register_endpoint(MyClientRegistrationEndpoint)

    # for Flask
    @app.route('/register', methods=['POST'])
    def client_registration():
        return authorization_server.create_endpoint_response('client_registration')

    # for Django
    from django.views.decorators.http import require_http_methods

    @require_http_methods(["POST"])
    def client_registration(request):
        return authorization_server.create_endpoint_response('client_registration', request)

## API Reference

class authlib.oauth2.rfc7591.ClientRegistrationEndpoint(server=None, claims_classes=None)

  The client registration endpoint is an OAuth 2.0 endpoint designed to allow a client to be registered with the authorization server.

  software_statement_alg_values_supported = None

    Rewrite this value with a list to support `software_statement` e.g. `software_statement_alg_values_supported = ['RS256']`

  generate_client_registration_info(client, request)

    Generate ``registration_client_uri` and `registration_access_token` for RFC7592. This method returns `None` by default. Developers MAY rewrite this method to return registration information.

  generate_client_id()

    Generate `client_id` value. Developers MAY rewrite this method to use their own way to generate `client_id`.

  generate_client_secret()

    Generate `client_secret` value. Developers MAY rewrite this method to use their own way to generate `client_secret`.

  get_server_metadata()

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

  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

  resolve_public_key(request)

    Resolve a public key for decoding `software_statement`. If `enable_software_statement=True`, developers MUST implement this method in subclass:

        def resolve_public_key(self, request):
            return get_public_key_from_user(request.credential)

    Returns:

      JWK or Key string

  save_client(client_info, client_metadata, request)

    Save client into database. Developers MUST implement this method in subclass:

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

class authlib.oauth2.rfc7591.ClientMetadataClaims(payload, header, options=None, params=None)
  validate_redirect_uris()

    Array of redirection URI strings for use in redirect-based flows such as the authorization code and implicit flows. As required by Section 2 of OAuth 2.0 [RFC6749], clients using flows with redirection MUST register their redirection URI values. Authorization servers that support dynamic registration for redirect-based flows MUST implement support for this metadata value.

  validate_token_endpoint_auth_method()

    String indicator of the requested authentication method for the token endpoint.

  validate_grant_types()

    Array of OAuth 2.0 grant type strings that the client can use at the token endpoint.

  validate_response_types()

    Array of the OAuth 2.0 response type strings that the client can use at the authorization endpoint.

  validate_client_name()

    Human-readable string name of the client to be presented to the end-user during authorization. If omitted, the authorization server MAY display the raw “client_id” value to the end-user instead. It is RECOMMENDED that clients always send this field. The value of this field MAY be internationalized, as described in Section 2.2.

  validate_client_uri()

    URL string of a web page providing information about the client. If present, the server SHOULD display this URL to the end-user in a clickable fashion. It is RECOMMENDED that clients always send this field. The value of this field MUST point to a valid web page. The value of this field MAY be internationalized, as described in Section 2.2.

  validate_logo_uri()

    URL string that references a logo for the client. If present, the server SHOULD display this image to the end-user during approval. The value of this field MUST point to a valid image file. The value of this field MAY be internationalized, as described in Section 2.2.

  validate_scope()

    String containing a space-separated list of scope values (as described in Section 3.3 of OAuth 2.0 [RFC6749]) that the client can use when requesting access tokens. The semantics of values in this list are service specific. If omitted, an authorization server MAY register a client with a default set of scopes.

  validate_contacts()

    Array of strings representing ways to contact people responsible for this client, typically email addresses. The authorization server MAY make these contact addresses available to end-users for support requests for the client. See Section 6 for information on Privacy Considerations.

  validate_tos_uri()

    URL string that points to a human-readable terms of service document for the client that describes a contractual relationship between the end-user and the client that the end-user accepts when authorizing the client. The authorization server SHOULD display this URL to the end-user if it is provided. The value of this field MUST point to a valid web page. The value of this field MAY be internationalized, as described in Section 2.2.

  validate_policy_uri()

    URL string that points to a human-readable privacy policy document that describes how the deployment organization collects, uses, retains, and discloses personal data. The authorization server SHOULD display this URL to the end-user if it is provided. The value of this field MUST point to a valid web page. The value of this field MAY be internationalized, as described in Section 2.2.

  validate_jwks_uri()

    URL string referencing the client’s JSON Web Key (JWK) Set [RFC7517] document, which contains the client’s public keys. The value of this field MUST point to a valid JWK Set document. These keys can be used by higher-level protocols that use signing or encryption. For instance, these keys might be used by some applications for validating signed requests made to the token endpoint when using JWTs for client authentication [RFC7523]. Use of this parameter is preferred over the “jwks” parameter, as it allows for easier key rotation. The “jwks_uri” and “jwks” parameters MUST NOT both be present in the same request or response.

  validate_jwks()

    Client’s JSON Web Key Set [RFC7517] document value, which contains the client’s public keys. The value of this field MUST be a JSON object containing a valid JWK Set. These keys can be used by higher-level protocols that use signing or encryption. This parameter is intended to be used by clients that cannot use the “jwks_uri” parameter, such as native clients that cannot host public URLs. The “jwks_uri” and “jwks” parameters MUST NOT both be present in the same request or response.

  validate_software_id()

    A unique identifier string (e.g., a Universally Unique Identifier (UUID)) assigned by the client developer or software publisher used by registration endpoints to identify the client software to be dynamically registered. Unlike “client_id”, which is issued by the authorization server and SHOULD vary between instances, the “software_id” SHOULD remain the same for all instances of the client software. The “software_id” SHOULD remain the same across multiple updates or versions of the same piece of software. The value of this field is not intended to be human readable and is usually opaque to the client and authorization server.

  validate_software_version()

    A version identifier string for the client software identified by “software_id”. The value of the “software_version” SHOULD change on any update to the client software identified by the same “software_id”. The value of this field is intended to be compared using string equality matching and no other comparison semantics are defined by this specification. The value of this field is outside the scope of this specification, but it is not intended to be human readable and is usually opaque to the client and authorization server. The definition of what constitutes an update to client software that would trigger a change to this value is specific to the software itself and is outside the scope of this specification.

  classmethod get_claims_options(metadata)

    Generate claims options validation from Authorization Server metadata.