From e55bfd92514609784a205ee52d5b474fec0710c4 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Tue, 1 Apr 2014 12:15:40 +0000 Subject: [PATCH] BUG8446, Follow up: Improve local login fallback - Local fallback was not very well implimented, this patch adds better handling for such cases allowing clearer failure messages - This patch also adds the ability to use single sign on via the top bar menu in the bootstrap theme. BUG8446, Follow up: Adds perldoc documentation - Add some documentation to the Auth_with_Shibboleth module including some guidance as to configuration. --- C4/Auth.pm | 50 ++++++++---- C4/Auth_with_Shibboleth.pm | 83 ++++++++++++++++++++ .../opac-tmpl/bootstrap/en/includes/masthead.inc | 13 ++- .../opac-tmpl/bootstrap/en/modules/opac-auth.tt | 14 ++-- opac/opac-main.pl | 8 +- 5 files changed, 145 insertions(+), 23 deletions(-) diff --git a/C4/Auth.pm b/C4/Auth.pm index 1df90d5..75d6d21 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -63,8 +63,10 @@ BEGIN { import C4::Auth_with_ldap qw(checkpw_ldap); } if ($shib) { - import C4::Auth_with_Shibboleth qw(checkpw_shib logout_shib login_shib_url get_login_shib); - # Getting user login + import C4::Auth_with_Shibboleth + qw(checkpw_shib logout_shib login_shib_url get_login_shib); + + # Get shibboleth login attribute $shib_login = get_login_shib(); } if ($cas) { @@ -288,6 +290,13 @@ sub get_template_and_user { } else { # if this is an anonymous session, setup to display public lists... + # If shibboleth is enabled, and we have a shibboleth login attribute, + # but we are in an anonymouse session, we clearly have an invalid + # Shibboleth account. + if ( $shib && $shib_login ) { + $template->param( invalidShibLogin => '1'); + } + $template->param( sessionID => $sessionID ); my ($total, $pubshelves) = C4::VirtualShelves::GetSomeShelfNames(undef, 'MASTHEAD'); @@ -718,6 +727,8 @@ sub checkauth { } elsif ($logout) { # voluntary logout the user + # check wether the user was using their shibboleth session or a local one + my $shibSuccess = C4::Context->userenv->{'shibboleth'}; $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); @@ -729,8 +740,8 @@ sub checkauth { logout_cas($query); } - # If we are in a shibboleth session (shibboleth is enabled, and a shibboleth username is set) - if ( $shib and $shib_login and $type eq 'opac') { + # If we are in a shibboleth session (shibboleth is enabled, a shibboleth match attribute is set and matches koha matchpoint) + if ( $shib and $shib_login and $shibSuccess and $type eq 'opac') { # (Note: $type eq 'opac' condition should be removed when shibboleth authentication for intranet will be implemented) logout_shib($query); } @@ -803,20 +814,26 @@ sub checkauth { } if ( ( $cas && $query->param('ticket') ) || $userid - || $shib + || ( $shib && $shib_login ) || $pki_field ne 'None' || $persona ) { my $password = $query->param('password'); + my $shibSuccess = 0; my ( $return, $cardnumber ); - if ($shib && $shib_login && $type eq 'opac' && !$password) { + # If shib is enabled and we have a shib login, does the login match a valid koha user + if ( $shib && $shib_login && $type eq 'opac' ) { my $retuserid; - ( $return, $cardnumber, $retuserid ) = checkpw( $dbh, $userid, $password, $query ); + # Do not pass password here, else shib will not be checked in checkpw. + ( $return, $cardnumber, $retuserid ) = checkpw( $dbh, $userid, undef, $query ); $userid = $retuserid; + $shibSuccess = $return; $info{'invalidShibLogin'} = 1 unless ($return); - - } elsif ( $cas && $query->param('ticket') ) { + } + # If shib login and match were successfull, skip further login methods + unless ( $shibSuccess ) { + if ( $cas && $query->param('ticket') ) { my $retuserid; ( $return, $cardnumber, $retuserid ) = checkpw( $dbh, $userid, $password, $query ); @@ -883,7 +900,8 @@ sub checkauth { ( $return, $cardnumber, $retuserid ) = checkpw( $dbh, $userid, $password, $query ); $userid = $retuserid if ( $retuserid ); - } + $info{'invalid_username_or_password'} = 1 unless ($return); + } } if ($return) { #_session_log(sprintf "%20s from %16s logged in at %30s.\n", $userid,$ENV{'REMOTE_ADDR'},(strftime '%c', localtime)); if ( $flags = haspermission( $userid, $flagsrequired ) ) { @@ -971,6 +989,7 @@ sub checkauth { $session->param('emailaddress',$emailaddress); $session->param('ip',$session->remote_addr()); $session->param('lasttime',time()); + $session->param('shibboleth',$shibSuccess); $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ; } elsif ( $return == 2 ) { @@ -997,7 +1016,7 @@ sub checkauth { $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), $session->param('emailaddress'), $session->param('branchprinter'), - $session->param('persona') + $session->param('persona'), $session->param('shibboleth') ); } @@ -1557,7 +1576,6 @@ sub get_session { sub checkpw { my ( $dbh, $userid, $password, $query ) = @_; - if ($ldap) { $debug and print STDERR "## checkpw - checking LDAP\n"; my ($retval,$retcard,$retuserid) = checkpw_ldap(@_); # EXTERNAL AUTH @@ -1573,12 +1591,14 @@ sub checkpw { return 0; } - # If we are in a shibboleth session (shibboleth is enabled and no password has been provided) - if ($shib && !$password) { + # If we are in a shibboleth session (shibboleth is enabled, and a shibboleth match attribute is present) + # Check for password to asertain whether we want to be testing against shibboleth or another method this + # time around. + if ($shib && $shib_login && !$password) { $debug and print STDERR "## checkpw - checking Shibboleth\n"; # In case of a Shibboleth authentication, we expect a shibboleth user attribute - # (defined in the shibbolethLoginAttribute) tto contain the login of the + # (defined under shibboleth mapping in koha-conf.xml) to contain the login of the # shibboleth-authenticated user # Then, we check if it matches a valid koha user diff --git a/C4/Auth_with_Shibboleth.pm b/C4/Auth_with_Shibboleth.pm index 5c6c6b3..8dd3083 100644 --- a/C4/Auth_with_Shibboleth.pm +++ b/C4/Auth_with_Shibboleth.pm @@ -105,3 +105,86 @@ sub checkpw_shib { } 1; +__END__ + +=head1 NAME + +C4::Auth_with_shibboleth + +=head1 SYNOPSIS + +use C4::Auth_with_shibboleth + +=head1 DESCRIPTION + +This module is specific to Shibboleth authentication in koha and relies heavily upon the native shibboleth service provider package in your operating system. + +=head1 CONFIGURATION + +To use this type of authentication these additional packages are required: + +=over + +=item * + +libapache2-mod-shib2 + +=item * + +libshibsp5:amd64 + +=item * + +shibboleth-sp2-schemas + +=back + +We let the native shibboleth service provider packages handle all the complexities of shibboleth negotiation for use and configuring this is beyond the scope of this documentation; But to sum up, you will need to: + +=over + +=item 1. + +Create some metadata for your koha instance (if you're in a single instance setup then the default metadata available at https://youraddress.com/Shibboleth.sso/Metadata should be adequate) + +=item 2. + +Swap metadata with your Identidy Provider (IdP) + +=item 3. + +Map their attributes to what you want to see in koha + +=item 4. + +Tell apache that we wish to allow koha to authenticate via shibboleth; This is as simple as adding the below to your virtualhost config: + +=begin text + + + AuthType shibboleth + Require shibboleth + + +=end text + +=item 5. + +Configure koha to listen for shibboleth environment variables; To do this we add 1 for the koha-conf.xml file + +=item 6. + +Map shibboleth attributes to koha fields in koha-conf.xml. + + + + eduPersonID + + + + +=back + +=head1 FUNCTIONS + +=cut diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc index 1edc244..ac40f11 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc +++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc @@ -272,6 +272,17 @@
- \ No newline at end of file + diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt index a1cf15e..67401c3 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt @@ -58,18 +58,20 @@ [% END %] [% IF ( shibbolethAuthentication ) %] -

Shibboleth Login

[% IF ( invalidShibLogin ) %] - -

Sorry, the Shibboleth login failed.

- [% END %] + +
+

Sorry, your Shibboleth identity does not match a valid library identity. If you have a local login, you may use that below.

+
+ [% ELSE %] +

Shibboleth Login

If you have a Shibboleth account, please click here to login.

- + [% END %]

Local Login

-

If you do not have a Shibboleth account, but a local account, you can still log in :

+

If you do not have a Shibboleth account, but a local account, you can still log in:

[% END %] diff --git a/opac/opac-main.pl b/opac/opac-main.pl index fb9de41..741727d 100755 --- a/opac/opac-main.pl +++ b/opac/opac-main.pl @@ -20,6 +20,7 @@ use strict; use warnings; use CGI; use C4::Auth; # get_template_and_user +use C4::Auth_with_Shibboleth qw( login_shib_url ); use C4::Output; use C4::NewsChannels; # get_opac_news use C4::Languages qw(getTranslatedLanguages accept_language); @@ -43,7 +44,12 @@ $template->param( casAuthentication => $casAuthentication, ); -$template->param( shibbolethAuthentication => C4::Context->config('useshibboleth') ); +if ( C4::Context->config('useshibboleth') ) { + $template->param( + shibbolethAuthentication => C4::Context->config('useshibboleth'), + shibbolethLoginUrl => C4::Auth_with_Shibboleth::login_shib_url($input) + ); +}; # display news # use cookie setting for language, bug default to syspref if it's not set -- 1.7.10.4