RFC9101: The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)¶
This section contains the generic implementation of RFC9101.
This specification describe how to pass the authorization request payload in a JWT (called request object) instead of directly instead of GET or POST params.
The request object can either be passed directly in a request
parameter,
or be hosted by the client and be passed by reference with a request_uri
parameter.
This usage is more secure than passing the request payload directly in the request, read the RFC to know all the details.
Request objects are optional, unless it is enforced by clients with the
require_signed_request_object
client metadata, or server-wide with the
require_signed_request_object
server metadata.
API Reference¶
- class authlib.oauth2.rfc9101.JWTAuthenticationRequest(support_request: bool = True, support_request_uri: bool = True)¶
Authorization server extension implementing the support for JWT secured authentication request, as defined in RFC9101.
- Parameters:
support_request – Whether to enable support for the
request
parameter.support_request_uri – Whether to enable support for the
request_uri
parameter.
This extension is intended to be inherited and registered into the authorization server:
class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest): def resolve_client_public_key(self, client: ClientMixin): return get_jwks_for_client(client) def get_request_object(self, request_uri: str): try: return requests.get(request_uri).text except requests.Exception: return None def get_server_metadata(self): return { "issuer": ..., "authorization_endpoint": ..., "require_signed_request_object": ..., } def get_client_require_signed_request_object(self, client: ClientMixin): return client.require_signed_request_object authorization_server.register_extension(JWTAuthenticationRequest())
- get_request_object(request_uri: str)¶
Download the request object at
request_uri
.This method must be implemented if the
request_uri
parameter is supported:class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest): def get_request_object(self, request_uri: str): try: return requests.get(request_uri).text except requests.Exception: return None
- resolve_client_public_keys(client: ClientMixin)¶
Resolve the client public key for verifying the JWT signature. A client may have many public keys, in this case, we can retrieve it via
kid
value in headers. Developers MUST implement this method:class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest): def resolve_client_public_key(self, client): if client.jwks_uri: return requests.get(client.jwks_uri).json return client.jwks
- get_server_metadata() → dict¶
Return server metadata which includes supported grant types, response types and etc.
When the
require_signed_request_object
claim isTrue
, all clients require that authorization requests use request objects, and an error will be returned when the authorization request payload is passed in the request body or query string:class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest): def get_server_metadata(self): return { "issuer": ..., "authorization_endpoint": ..., "require_signed_request_object": ..., }
- get_client_require_signed_request_object(client: ClientMixin) → bool¶
Return the ‘require_signed_request_object’ client metadata.
When
True
, the client requires that authorization requests use request objects, and an error will be returned when the authorization request payload is passed in the request body or query string:class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest): def get_client_require_signed_request_object(self, client): return client.require_signed_request_object
If not implemented, the value is considered as
False
.
- class authlib.oauth2.rfc9101.ClientMetadataClaims(payload, header, options=None, params=None)¶
Additional client metadata can be used with RFC7591: OAuth 2.0 Dynamic Client Registration Protocol and RFC7592: OAuth 2.0 Dynamic Client Registration Management Protocol endpoints.
This can be used with:
server.register_endpoint( ClientRegistrationEndpoint( claims_classes=[ rfc7591.ClientMetadataClaims, rfc9101.ClientMetadataClaims, ] ) ) server.register_endpoint( ClientRegistrationEndpoint( claims_classes=[ rfc7591.ClientMetadataClaims, rfc9101.ClientMetadataClaims, ] ) )