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 is True, 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,
        ]
    )
)
class authlib.oauth2.rfc9101.AuthorizationServerMetadata
validate_require_signed_request_object()

Indicates where authorization request needs to be protected as Request Object and provided through either request or request_uri parameter.