docs/specs/rfc7591.rst
.. _specs/rfc7591:
RFC7591: OAuth 2.0 Dynamic Client Registration Protocol
=======================================================
.. meta::
:description: Python API references on RFC7591 OAuth 2.0 Dynamic Client
Registration Protocol in Python with Authlib implementation.
.. module:: authlib.oauth2.rfc7591
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 :ref:`flask_oauth2_server` or :ref:`django_oauth2_server`,
developers MUST implement the missing methods of :class:`ClientRegistrationEndpoint`.
.. _RFC7591: https://tools.ietf.org/html/rfc7591
Client Registration Endpoint
----------------------------
The client registration endpoint accepts client metadata as JSON payload via
POST request. The metadata may contain a :ref:`JWT <jwt_guide>` ``software_statement``
value. Endpoint can choose if it support ``software_statement``, it is not enabled
by default.
.. versionchanged:: 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
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
-------------
.. autoclass:: ClientRegistrationEndpoint
:member-order: bysource
:members:
.. autoclass:: ClientMetadataClaims
:member-order: bysource
:members: