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