OpenID Connect RP-Initiated Logout 1.0¶
This section contains the generic implementation of OpenID Connect RP-Initiated Logout 1.0. This specification enables Relying Parties (RPs) to request that an OpenID Provider (OP) log out the End-User.
End Session Endpoint¶
To add RP-Initiated Logout support, create a subclass of EndSessionEndpoint
and implement the required methods:
from authlib.oidc.rpinitiated import EndSessionEndpoint
class MyEndSessionEndpoint(EndSessionEndpoint):
def get_server_jwks(self):
return load_jwks()
def end_session(self, end_session_request):
# Terminate user session
session.clear()
server.register_endpoint(MyEndSessionEndpoint)
Then create a logout route. You have two options:
Non-interactive mode (simple, no confirmation page):
@app.route('/logout', methods=['GET', 'POST'])
def logout():
return (
server.create_endpoint_response("end_session")
or render_template('logged_out.html')
)
Interactive mode (with confirmation page):
@app.route('/logout', methods=['GET', 'POST'])
def logout():
try:
req = server.validate_endpoint_request("end_session")
except OAuth2Error as error:
return server.handle_error_response(None, error)
# Show confirmation page on GET when no id_token_hint was provided
# User confirms by submitting the form (POST)
if req.needs_confirmation and request.method == 'GET':
return render_template('confirm_logout.html', client=req.client)
return (
server.create_endpoint_response("end_session", req)
or render_template('logged_out.html')
)
The create_endpoint_response method returns None when there is no
post_logout_redirect_uri, allowing you to provide your own response page.
Request Parameters¶
The endpoint accepts the following parameters (via GET or POST):
id_token_hint (Recommended): A previously issued ID Token passed as a hint about the End-User’s authenticated session.
logout_hint (Optional): A hint to the OP about the End-User that is logging out.
client_id (Optional): The OAuth 2.0 Client Identifier. When both
client_idandid_token_hintare present, the OP verifies that the Client Identifier matches theaudclaim in the ID Token.post_logout_redirect_uri (Optional): URI to which the End-User’s User Agent is redirected after logout. Must exactly match a pre-registered value.
state (Optional): Opaque value used by the RP to maintain state between the logout request and the callback.
ui_locales (Optional): End-User’s preferred languages for the user interface.
Confirmation Flow¶
Per the specification, logout requests without a valid id_token_hint are a
potential means of denial of service. The EndSessionRequest.needs_confirmation
property indicates when user confirmation is recommended.
You control the confirmation page rendering - simply check needs_confirmation
and render your own template as shown in the interactive mode example above.
Post-Logout Redirection¶
Post-logout redirection only happens when:
A
post_logout_redirect_uriis providedThe client is resolved (via
id_token_hintorclient_id)The URI is registered in the client’s
post_logout_redirect_uris
If all conditions are met, EndSessionRequest.redirect_uri contains the
validated URI (with state appended if provided).
If conditions are not met, create_endpoint_response returns None and
you should provide a default logout page:
server.create_endpoint_response("end_session", req) or render_template('logged_out.html')
Session Validation¶
When an id_token_hint is provided, the id_token_claims attribute of
EndSessionRequest contains all claims from the ID Token, including
sid (session ID) if present.
Per the specification, you SHOULD verify that the sid matches the current
session to detect potentially suspect logout requests:
def end_session(self, end_session_request):
if end_session_request.id_token_claims:
sid = end_session_request.id_token_claims.get("sid")
if sid and sid != get_current_session_id():
# Treat as suspect - may require additional confirmation
pass
session.clear()
Client Registration¶
Relying Parties can register their post_logout_redirect_uris through
RFC7591: OAuth 2.0 Dynamic Client Registration Protocol.
To support RP-Initiated Logout client metadata, add the claims class to your registration and configuration endpoints:
from authlib import oidc
from authlib.oauth2 import rfc7591
authorization_server.register_endpoint(
ClientRegistrationEndpoint(
claims_classes=[
rfc7591.ClientMetadataClaims,
oidc.registration.ClientMetadataClaims,
oidc.rpinitiated.ClientMetadataClaims,
]
)
)
The post_logout_redirect_uris parameter is an array of URLs to which the
End-User’s User Agent may be redirected after logout. These URLs SHOULD use
the https scheme.
API Reference¶
- class authlib.oidc.rpinitiated.EndSessionEndpoint(server=None)¶
OpenID Connect RP-Initiated Logout endpoint.
This endpoint follows a two-phase pattern for interactive flows:
Call
server.validate_endpoint_request("end_session")to validate the request and get anEndSessionRequestCheck
end_session_request.needs_confirmationand show UI if neededCall
server.create_endpoint_response("end_session", end_session_request)to execute logout and create the response
Example usage:
class MyEndSessionEndpoint(EndSessionEndpoint): def get_server_jwks(self): return load_jwks() def end_session(self, end_session_request): session.clear() server.register_endpoint(MyEndSessionEndpoint) @app.route("/logout", methods=["GET", "POST"]) def logout(): try: req = server.validate_endpoint_request("end_session") except OAuth2Error as error: return server.handle_error_response(None, error) if req.needs_confirmation and request.method == "GET": return render_template("confirm_logout.html", client=req.client) return server.create_endpoint_response( "end_session", req ) or render_template("logged_out.html")
For non-interactive usage (no confirmation page), use the standard pattern:
@app.route("/logout", methods=["GET", "POST"]) def logout(): return server.create_endpoint_response("end_session") or render_template( "logged_out.html" )
- ENDPOINT_NAME: str | None = 'end_session'¶
Endpoint name used for registration
- validate_request(request: OAuth2Request) EndSessionRequest¶
Validate an end session request.
- Parameters:
request – The OAuth2Request to validate
- Returns:
EndSessionRequest with validated data
- Raises:
InvalidRequestError – If validation fails
- create_response(validated_request: EndSessionRequest) tuple[int, Any, list[tuple[str, str]]] | None¶
Create the end session HTTP response.
Executes the logout via
end_session(), then returns a redirect response if a valid redirect_uri is present, or None to let the application provide its own response.- Parameters:
validated_request – The validated EndSessionRequest
- Returns:
Tuple of (status_code, body, headers) for redirect, or None
- resolve_client_from_id_token_claims(id_token_claims: dict) Any | None¶
Resolve client from id_token aud claim.
When aud is a single string, resolves the client directly. When aud is a list, returns None (ambiguous case). Override for custom resolution logic.
- is_post_logout_redirect_uri_legitimate(request: OAuth2Request, post_logout_redirect_uri: str, client, logout_hint: str | None) bool¶
Confirm redirect_uri legitimacy when no id_token_hint is provided.
Override if you have alternative confirmation mechanisms, e.g.:
def is_post_logout_redirect_uri_legitimate(self, ...): return client and client.is_trusted
By default returns False (no redirection without id_token_hint).
- get_server_jwks() dict | KeySet¶
Return the server’s JSON Web Key Set for validating ID tokens.
- get_algorithms() list[str]¶
Return the list of allowed algorithms for ID token validation.
By default, returns all algorithms compatible with the keys in the JWKS. Override to restrict to specific algorithms.
- end_session(end_session_request: EndSessionRequest) None¶
Terminate the user’s session.
Implement this method to perform the actual logout logic, such as clearing session data, revoking tokens, etc.
Use
end_session_request.logout_hintto help identify the user (e.g. email, username) when noid_token_hintis provided.- Parameters:
end_session_request – The validated EndSessionRequest
- class authlib.oidc.rpinitiated.EndSessionRequest(request: OAuth2Request, client: Any = None, id_token_claims: dict | None = None, redirect_uri: str | None = None, logout_hint: str | None = None, ui_locales: str | None = None)¶
Validated end session request data.
This object is returned by
EndSessionEndpoint.validate_request()and contains all the validated information from the logout request.- property needs_confirmation: bool¶
Whether user confirmation is recommended before logout.
- class authlib.oidc.rpinitiated.ClientMetadataClaims(claims: dict[str, Any], header: dict[str, Any], options: dict[str, ClaimsOption] | None = None, params: dict[str, Any] = None)¶
Client metadata for OpenID Connect RP-Initiated Logout 1.0.
This can be used with RFC7591: OAuth 2.0 Dynamic Client Registration Protocol and RFC7592: OAuth 2.0 Dynamic Client Registration Management Protocol endpoints:
server.register_endpoint( ClientRegistrationEndpoint( claims_classes=[ rfc7591.ClientMetadataClaims, oidc.registration.ClientMetadataClaims, oidc.rpinitiated.ClientMetadataClaims, ] ) )
- class authlib.oidc.rpinitiated.OpenIDProviderMetadata¶