authlib
authlib copied to clipboard
Loggout support
Is your feature request related to a problem? Please describe.
I'd like Authlib to support logging out of open id connect servers. AFAIK this is handled through an additional spec - and I'm not sure I understand fully which spec is required for that.
Describe the solution you'd like
Login in Flask land pretty much looks like this:
@app.route('/auth/login')
def login():
store_came_from()
redirect_url = flask.url_for('authorize', _external=True)
return oauth.oidc.authorize_redirect(redirect_url)
I wrote my own logout method like this:
@app.route('/auth/logout')
def logout():
try:
# According to OIDC spec end_session_endpoint is optional, so we can't rely on it being present
if not has_valid_oidc_user() or not does_support_deauthorize():
return flask.redirect(flask.request.args['came_from'])
store_came_from()
redirect_uri = flask.url_for('deauthorize', _external=True)
return deauthorize_redirect(redirect_uri)
finally:
# make sure we clean the session
flask.session.pop('token', None)
It would be quite helpful if the library was able to create the deauthorize_redirect() the same way that it creates the authorize_redirect().
My version is quite simple, but took surprisingly long to get it right:
def deauthorize_redirect(redirect_url):
metadata = oauth.oidc.load_server_metadata()
end_session_endpoint = metadata.get('end_session_endpoint')
token = token_from_session()
end_session_url = add_params_to_uri(end_session_endpoint, (
('id_token_hint', token['id_token']),
('post_logout_redirect_uri', redirect_url),
))
return flask.redirect(end_session_url)
Describe alternatives you've considered
I implemented something myself - but I think this would be a very nice addition to the library.
end_session_endpoint is defined by OpenID Connect Session Management 1.0, but this spec is still in draft status. I'm not going to add it until it is published.
This seems to be related to #292. end_session is mentioned in:
- https://openid.net/specs/openid-connect-rpinitiated-1_0.html
- https://openid.net/specs/openid-connect-session-1_0.html
- https://openid.net/specs/openid-connect-frontchannel-1_0.html
- https://openid.net/specs/openid-connect-backchannel-1_0.html
closed in favor of https://github.com/lepture/authlib/issues/292
It will be implemented in v1.3
Hi
I am trying to implement @dwt's logout session method. However it puzzles me how did he routed to the endpoint (deauthorize).
def deauthorize_redirect(redirect_url):
metadata = grundfos.load_server_metadata()
end_session_endpoint = metadata.get("end_session_endpoint")
token = session.get("token")
end_session_url = add_params_to_uri(
end_session_endpoint,
(
("id_token_hint", token["id_token"]),
("post_logout_redirect_uri", redirect_url),
),
)
return redirect(end_session_url)
So I cannot generate the redirect_uri , because the app doesn't have deauthorize endpoint.
@server.route("/logout")
def logout():
# make sure we clean the session
try:
#Fails here, because there is no endpoint like deauthorize
redirect_uri = url_for('deauthorize', _external=True)
return deauthorize_redirect(redirect_uri)
finally:
# make sure we clean the session
session.pop('token', None)
So question, how do you add or generate this redirect_uri ?
Error message:
werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'deauthorize'. Did you mean 'authorize' instead?
I understand there is no deauthorize.
Thanks
David
@nagydavid Well, as you see in the example above, I implemented the endpoint /auth/logout myself - does that help you?