diff options
author | Rob Crittenden <rcritten@redhat.com> | 2015-03-25 17:29:22 -0400 |
---|---|---|
committer | Patrick Uiterwijk <puiterwijk@redhat.com> | 2015-03-27 19:43:26 +0100 |
commit | 83ac397cd5904cbbaa5a21adcac73815dda9fa63 (patch) | |
tree | 8aa04ef6a057469f02cb8356a7c6a8601e3abefb | |
parent | 0f56ef9942ee631a9306806bea8f3bb8e7b81076 (diff) | |
download | ipsilon-83ac397cd5904cbbaa5a21adcac73815dda9fa63.tar.gz ipsilon-83ac397cd5904cbbaa5a21adcac73815dda9fa63.tar.xz ipsilon-83ac397cd5904cbbaa5a21adcac73815dda9fa63.zip |
Try to return a redirect instead a 400 for "not logged in" state
If the user is not logged in and submits a valid logout request
then just redirect the user to the RelayState in the request
indicating that the logout was successful. This provides a better
user experience.
https://fedorahosted.org/ipsilon/ticket/88
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
-rw-r--r-- | ipsilon/providers/saml2/logout.py | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/ipsilon/providers/saml2/logout.py b/ipsilon/providers/saml2/logout.py index da8edcf..bfb5d0d 100644 --- a/ipsilon/providers/saml2/logout.py +++ b/ipsilon/providers/saml2/logout.py @@ -80,15 +80,14 @@ class LogoutRequest(ProviderPageBase): self.error('loading session failed: %s' % e) raise cherrypy.HTTPError(400, 'Invalid logout session') else: - self.error('Logout attempt without being loggged in.') - raise cherrypy.HTTPError(400, 'Not logged in') + return self._not_logged_in(logout, message) try: logout.validateRequest() except lasso.ProfileSessionNotFoundError, e: self.error('Logout failed. No sessions for %s' % logout.remoteProviderId) - raise cherrypy.HTTPError(400, 'Not logged in') + return self._not_logged_in(logout, message) except lasso.LogoutUnsupportedProfileError: self.error('Logout failed. Unsupported profile %s' % logout.remoteProviderId) @@ -156,11 +155,48 @@ class LogoutRequest(ProviderPageBase): (user.name, user.fullname, logout.remoteProviderId)) else: - self.error('Logout attempt without being loggged in.') - raise cherrypy.HTTPError(400, 'Not logged in') + return self._not_logged_in(logout, message) return + def _not_logged_in(self, logout, message): + """ + The user requested a logout but isn't logged in, or we can't + find a session for the user. Try to be nice and redirect them + back to the RelayState in the logout request. + + We are only nice in the case of a valid logout request. If the + request is invalid (not signed, unknown SP, etc) then an + exception is raised. + """ + self.error('Logout attempt without being logged in.') + + if logout.msgRelayState is not None: + raise cherrypy.HTTPRedirect(logout.msgRelayState) + + try: + logout.processRequestMsg(message) + except (lasso.ServerProviderNotFoundError, + lasso.ProfileUnknownProviderError) as e: + msg = 'Invalid SP [%s] (%r [%r])' % (logout.remoteProviderId, + e, message) + self.error(msg) + raise UnknownProvider(msg) + except (lasso.ProfileInvalidProtocolprofileError, + lasso.DsError), e: + msg = 'Invalid SAML Request: %r (%r [%r])' % (logout.request, + e, message) + self.error(msg) + raise InvalidRequest(msg) + except lasso.Error, e: + self.error('SLO unknown error: %s' % message) + raise cherrypy.HTTPError(400, 'Invalid logout request') + + if logout.msgRelayState: + raise cherrypy.HTTPRedirect(logout.msgRelayState) + else: + raise cherrypy.HTTPError(400, 'Not logged in') + def logout(self, message, relaystate=None, samlresponse=None): """ Handle HTTP Redirect logout. This is an asynchronous logout @@ -186,8 +222,7 @@ class LogoutRequest(ProviderPageBase): saml_sessions = us.get_provider_data('saml2') if saml_sessions is None: # No sessions means nothing to log out - self.error('Logout attempt without being loggged in.') - raise cherrypy.HTTPError(400, 'Not logged in') + return self._not_logged_in(logout, message) self.debug('%d sessions loaded' % saml_sessions.count()) saml_sessions.dump() @@ -244,8 +279,7 @@ class LogoutRequest(ProviderPageBase): saml_sessions = us.get_provider_data('saml2') if saml_sessions is None or saml_sessions.count() == 0: - self.error('Logout attempt without being loggged in.') - raise cherrypy.HTTPError(400, 'Not logged in') + return self._not_logged_in(logout, message) try: session = saml_sessions.get_last_session() |