From: Art Rhyno Date: Wed, 23 Jan 2013 04:35:40 +0000 (-0500) Subject: CAS Support for Evergreen X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=9f7129229acd5fb996dfffc648ae2e98b6fce5c2;p=contrib%2FConifer.git CAS Support for Evergreen This branch contains one approach to supporting CAS within Evergreen, I had originally thought of CAS as an "all or nothing" option but I have tried to make it possible to support standard authentication at the same time since we will have a transition period where some accounts won't be CAS-enabled and I suspect this is typical. As well, it is possible that a library will need to have the ability to add accounts outside of the campus directory. In /openils/conf/opensrf.xml, you would add CAS-specific values,for example true cas OpenILS::Application::AuthProxy::CAS_Auth_Conifer https://uwinid.uwindsor.ca/cas/proxyValidate https://localhost/eg/opac/login @uwindsor.ca native The entry point for CAS is in topnav.tt2, I have added a "cas_intro" option in order to give an introduction screen before passing a user to the CAS service:
[% l('Log in to Your Account (UWind ID)') %]
but you could just go directly to cas at this point:
[% l('Log in to Your Account (UWind ID)') %]
where ctx.cas.url is set in the config.tt2 file, for example: ctx.cas.url = 'https://uwinid.uwindsor.ca/cas/login?service=https://localhost/eg/opac/login'; I use a cookie to indicate that CAS has been used to authenticate, since it requires a slightly different logout sequence. This also gets reflected in topnav.tt2 if you are using both CAS and standard authentication: [% IF CGI.cookie('eg_CAS') %] [% l('Logout') %] [% ELSE %] [% l('Logout') %] [% END %] Note the "redirect_to", you will want to clear the session for logging out of tpac so that another user on a public station won't stumble into someone else's account. Again, if authentication is strictly CAS, then you can just use the CAS form of the logout. Signed-off-by: Art Rhyno --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/CAS_Auth_Conifer.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/CAS_Auth_Conifer.pm new file mode 100644 index 0000000000..83b1abb4f8 --- /dev/null +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/CAS_Auth_Conifer.pm @@ -0,0 +1,57 @@ +package OpenILS::Application::AuthProxy::CAS_Auth_Conifer; +use strict; +use warnings; +use base 'OpenILS::Application::AuthProxy::AuthBase'; +use OpenILS::Event; +use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::Logger qw(:logger); +use LWP::UserAgent; + +sub authenticate { + my ( $self, $args ) = @_; + + my $ticket = $args->{'ticket'}; + my $cas_validate_url = $self->{'cas_validate_url'}; + my $cas_service = $self->{'cas_service'}; + my $cas_suffix = $self->{'cas_suffix'}; + my $login_succeeded = 0; + + if ($ticket && $cas_validate_url && $cas_service) { + my $ua = LWP::UserAgent->new; + + # We can now go to the service with this ticket. + my $response = $ua->get( $cas_validate_url . '?ticket=' . $ticket . '&service=' . $cas_service); + + if ($response->is_success) { + my $content_str = $response->as_string; + # Does this ever vary? Every example seems to use this namespace + $content_str =~ /(.*)<\/cas:user>/; + my $username = $1; + if ($username) { + # The suffix is typically for e-mail + if ($cas_suffix) { + $username = $username . $cas_suffix; + } + # We now set the username + $args->{username} = $username; + # and add a flag for this type of authentication + $login_succeeded = 1; + } + } + } + + if ( $login_succeeded ) { + return OpenILS::Event->new('SUCCESS'); + } elsif ( !$ticket ) { + $logger->debug("CAS User login failed: Missing ticket"); + return OpenILS::Event->new( 'LOGIN_FAILED' ); + } elsif ( !$cas_validate_url || !$cas_service) { + $logger->debug("CAS User login failed: The CAS configuration is not complete"); + return OpenILS::Event->new( 'LOGIN_FAILED' ); + } else { + $logger->debug("User login failed: invalid CAS ticket"); + return OpenILS::Event->new( 'LOGIN_FAILED' ); + } +} + +1; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm index 6c88f83f9e..9e30cfd90c 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm @@ -28,6 +28,7 @@ my $U = 'OpenILS::Application::AppUtils'; use constant COOKIE_SES => 'ses'; use constant COOKIE_LOGGEDIN => 'eg_loggedin'; +use constant COOKIE_LOGGEDIN_CAS => 'eg_CAS'; use constant COOKIE_PHYSICAL_LOC => 'eg_physical_loc'; use constant COOKIE_SSS_EXPAND => 'eg_sss_expand'; @@ -131,6 +132,9 @@ sub load { return $self->load_cache_clear if $path =~ m|opac/cache/clear|; return $self->load_temp_warn_post if $path =~ m|opac/temp_warn/post|; return $self->load_temp_warn if $path =~ m|opac/temp_warn|; + # added for CAS support - we probably want a place to explain why someone is being + # redirected to a third party site + return $self->load_cas_intro if $path =~ m|opac/cas_intro|; # ---------------------------------------------------------------- # Everything below here requires SSL @@ -355,8 +359,16 @@ sub load_login { my $password = $cgi->param('password'); my $org_unit = $ctx->{physical_loc} || $ctx->{aou_tree}->()->id; my $persist = $cgi->param('persist'); + my $ticket = $cgi->param('ticket'); + my $cas_flag = '0'; # initial log form only + if ($ticket) { + # CAS does not have either username or password at this point, so we fudge these + # values for the other checks + $username = '_CAS_'; + $password = '_CAS_'; + } return Apache2::Const::OK unless $username and $password; # Should we append an email hostname to the username? @@ -405,6 +417,10 @@ sub load_login { 'open-ils.auth', 'open-ils.auth.authenticate.complete', $args); } else { $args->{password} = $password; + if ($ticket) { + $args->{ticket} = $ticket; + $cas_flag = '1'; + } $response = $U->simplereq( 'open-ils.auth_proxy', 'open-ils.auth_proxy.login', $args); @@ -416,7 +432,7 @@ sub load_login { $ctx->{login_failed_event} = $response; return Apache2::Const::OK; } - + # login succeeded, redirect as necessary my $acct = $self->apache->unparsed_uri; @@ -444,6 +460,14 @@ sub load_login { -secure => 0, -value => '1', -expires => $login_cookie_expires + ), + # contains only a hint that we are using CAS + $cgi->cookie( + -name => COOKIE_LOGGEDIN_CAS, + -path => '/', + -secure => 0, + -value => $cas_flag, + -expires => $login_cookie_expires ) ] ); @@ -475,6 +499,12 @@ sub load_logout { -path => '/', -value => '', -expires => '-1h' + ), + $self->cgi->cookie( + -name => COOKIE_LOGGEDIN_CAS, + -path => '/', + -value => '', + -expires => '-1h' ) ] ); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm index 445654dbea..b093e62419 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm @@ -221,4 +221,10 @@ sub load_temp_warn { return Apache2::Const::OK; } +sub load_cas_intro { + my $self = shift; + $self->ctx->{'redirect_to'} = $self->cgi->param('redirect_to'); + return Apache2::Const::OK; +} + 1; diff --git a/Open-ILS/src/templates/opac/cas_intro.tt2 b/Open-ILS/src/templates/opac/cas_intro.tt2 new file mode 100644 index 0000000000..7903349fe8 --- /dev/null +++ b/Open-ILS/src/templates/opac/cas_intro.tt2 @@ -0,0 +1,38 @@ +[% PROCESS "opac/parts/header.tt2"; + PROCESS "opac/parts/misc_util.tt2"; + WRAPPER "opac/parts/base.tt2"; + INCLUDE "opac/parts/topnav.tt2"; + + cas_alert = l('You have selected CAS Authentication. This will use your campus userid (also known as login or user name).'); + ctx.page_title = l("CAS Information") -%] +
+
+
+ + + + +
+
+
+
+[% END %] diff --git a/Open-ILS/src/templates/opac/parts/config.tt2 b/Open-ILS/src/templates/opac/parts/config.tt2 index 737c9a81b1..5fc219c7ba 100644 --- a/Open-ILS/src/templates/opac/parts/config.tt2 +++ b/Open-ILS/src/templates/opac/parts/config.tt2 @@ -28,6 +28,15 @@ ctx.refworks.url = 'http://www.refworks.com'; # ctx.refworks.url = 'http://librweb.laurentian.ca/login?url=http://refworks.scholarsportal.info'; ############################################################################## +# CAS support +############################################################################## +# Specify CAS URL for Login +# ctx.cas.url = 'https://myorg.org/cas/login?service=https://mylibrary.org/eg/opac/login'; +# Specify CAS URL for Logout +# ctx.cas.logout = 'https://myorg.org/cas/logout'; + + +############################################################################## # OpenURL resolution ############################################################################## # Evergreen provides the ability to point at an OpenURL resolver to find