From f16f7a84b73f83b6248560f212fddc1dd0c3b094 Mon Sep 17 00:00:00 2001 From: Jeff Godin Date: Tue, 24 Jul 2012 02:23:17 -0400 Subject: [PATCH] Fix TPAC recognition of logged-in users via http Fixes bug: LP 957375 tpac: catalog does not immediately recognize "stay logged in" users https://bugs.launchpad.net/evergreen/+bug/957375 The issue: during the login process, the user is redirected to an https connection and receives a cookie with the "secure" flag set. Since this cookie is not sent over normal http connections, following an external link or manually entering an http catalog url will result in an unexpected "not logged in" experience. Selecting the login link or any other action requiring login is enough to return to the "logged in" experience, without a need to re-enter credentials. Still, we can do better. This affects users who have checked the persistent login checkbox and those who have left it unchecked. Users selecting the persistent login option are more likely to encounter the issue, especially if the link they typically follow/enter is to a non-https catalog url. The solution: Add a new cookie (constant COOKIE_LOGGEDIN) - contains a "hint" that the user may be logged in already - set/cleared at login/logout time - contains no sensitive auth/session data - "secure" flag not set (sent for both http and https requests) When a user's browser presents the COOKIE_LOGGEDIN cookie in a request for a non-https URL, the user is automatically redirected to the https version of that url. At that time, if the user has a valid COOKIE_SES cookie set, they will be recognized as a logged in user. If their COOKIE_SES value is no longer valid, a logout is performed, clearing both cookies. If for some reason the COOKIE_SES cookie is not present but the COOKIE_LOGGEDIN is present, there is a harmless redirection to https and the user is not logged in, but can log in via the usual means. To test, after applying: - log in to the TPAC - navigate to http://example/eg/opac/home - You should be redirected to https://example/eg/opac/home and you should see your name, count of checked out / on hold / etc items Prior to this, the above steps would result in you remaining on the http URL and seeing only a "Your Account Log In" button. Signed-off-by: Jeff Godin Signed-off-by: Lebbeous Fogle-Weekley --- .../src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm | 56 +++++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm index 9d78bdaf6b..7154f666ec 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm @@ -27,6 +27,7 @@ use OpenILS::WWW::EGCatLoader::SMS; my $U = 'OpenILS::Application::AppUtils'; use constant COOKIE_SES => 'ses'; +use constant COOKIE_LOGGEDIN => 'eg_loggedin'; use constant COOKIE_PHYSICAL_LOC => 'eg_physical_loc'; use constant COOKIE_SSS_EXPAND => 'eg_sss_expand'; @@ -235,6 +236,11 @@ sub load_common { my $e = $self->editor; my $ctx = $self->ctx; + # redirect non-https to https if we think we are already logged in + if ($self->cgi->cookie(COOKIE_LOGGEDIN)) { + return $self->redirect_ssl unless $self->cgi->https; + } + $ctx->{referer} = $self->cgi->referer; $ctx->{path_info} = $self->cgi->path_info; $ctx->{full_path} = $ctx->{base_path} . $self->cgi->path_info; @@ -376,15 +382,30 @@ sub load_login { my $acct = $self->apache->unparsed_uri; $acct =~ s|/login|/myopac/main|; + # both login-related cookies should expire at the same time + my $login_cookie_expires = ($persist) ? CORE::time + $response->{payload}->{authtime} : undef; + return $self->generic_redirect( $cgi->param('redirect_to') || $acct, - $cgi->cookie( - -name => COOKIE_SES, - -path => '/', - -secure => 1, - -value => $response->{payload}->{authtoken}, - -expires => ($persist) ? CORE::time + $response->{payload}->{authtime} : undef - ) + [ + # contains the actual auth token and should be sent only over https + $cgi->cookie( + -name => COOKIE_SES, + -path => '/', + -secure => 1, + -value => $response->{payload}->{authtoken}, + -expires => $login_cookie_expires + ), + # contains only a hint that we are logged in, and is used to + # trigger a redirect to https + $cgi->cookie( + -name => COOKIE_LOGGEDIN, + -path => '/', + -secure => 0, + -value => '1', + -expires => $login_cookie_expires + ) + ] ); } @@ -401,12 +422,21 @@ sub load_logout { return $self->generic_redirect( $redirect_to || $self->ctx->{home_page}, - $self->cgi->cookie( - -name => COOKIE_SES, - -path => '/', - -value => '', - -expires => '-1h' - ) + [ + # clear value of and expire both of these login-related cookies + $self->cgi->cookie( + -name => COOKIE_SES, + -path => '/', + -value => '', + -expires => '-1h' + ), + $self->cgi->cookie( + -name => COOKIE_LOGGEDIN, + -path => '/', + -value => '', + -expires => '-1h' + ) + ] ); } -- 2.11.0