From: Dobrica Pavlinusic Date: Wed, 11 Sep 2019 11:16:44 +0000 (+0200) Subject: working SAML X-Git-Url: http://git.rot13.org/?p=share-koha-fer;a=commitdiff_plain;h=8d31d28a8bce0b3527ef12a9a36bb9864b9d413e working SAML --- diff --git a/lib/C4/Auth.pm b/lib/C4/Auth.pm index 7483417..aa47f6e 100644 --- a/lib/C4/Auth.pm +++ b/lib/C4/Auth.pm @@ -57,7 +57,7 @@ BEGIN { else { exit } } - $debug = $ENV{DEBUG}; + $debug = 1 || $ENV{DEBUG}; @ISA = qw(Exporter); @EXPORT = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions); @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &checkpw_internal &checkpw_hash @@ -834,34 +834,37 @@ sub checkauth { =cut -use Data::Dump qw(dump); + use Data::Dump qw(dump); warn "YYY ENV = ",dump( \%ENV ); $userid = $ENV{'HTTP_ATTR_CODE'}; -warn "XXX userid = [$userid] "; $sessionID = $query->cookie("CGISESSID"); +warn "XXX userid = [$userid] sessionID = $sessionID"; +=for xxx if ( $sessionID && $userid ) { my $s = get_session($sessionID); if ( $s->param('sessiontype') eq 'anon' ) { undef $sessionID; # remove anonymous session if we have SAML user + warn "XXX remote anonymous session"; } } # ($userid,$sessionID) = () if $userid eq '_everyone'; - return clear_saml($query) if $userid && $userid eq '_everyone'; +# return clear_saml($query) if $userid && $userid eq '_everyone'; - if ( ! $sessionID && $userid ) { # anonymous SAML user - warn "# userid: $userid"; +=cut # create new user from SAML data - if ( my $token = $query->cookie('AuthMemCookie') ) { - + my $token = $query->cookie('AuthMemCookie'); + if ( defined($token) ) { use Cache::Memcached; my $memd = new Cache::Memcached { 'servers' => [ '127.0.0.1:11211' ], 'compress_threshold' => 10_000 }; if ( my $data = $memd->get($token) ) { +warn "XXX AuthMemCookie $token = $data"; + my $saml; foreach ( split(/[\n\r]+/,$data) ) { my ($n,$v) = split /=/, $_; @@ -877,6 +880,7 @@ warn "XXX userid = [$userid] "; if ( my $borrowernumber = getborrowernumber($saml->{ATTR_nick}) ) { warn "SAML login OK $borrowernumber using ATTR_nick: ", $saml->{ATTR_nick}; + $userid = $saml->{ATTR_nick}; } elsif ( $borrowernumber = getborrowernumber( $cardnumber ) ) { warn "SAML login OK $borrowernumber using cardnumber: $cardnumber update userid: $userid"; my $sth = $dbh->prepare(qq{ update borrowers set userid = ? where userid = cardnumber and cardnumber = ? }); @@ -923,29 +927,59 @@ warn "XXX userid = [$userid] "; $sth->execute( $userid ); die "can't find $userid" unless $sth->rows; - my $session = get_session('') or die "can't create session"; - my $sessionID = $session->id; - C4::Context->_new_userenv($sessionID); - $cookie = $query->cookie(CGISESSID => $sessionID); + if ( $sessionID = $query->cookie("CGISESSID") ) { + warn "AAA updateing existing session $sessionID"; + $session = get_session($sessionID); + C4::Context->_new_userenv($sessionID); + } + if ( ! $session ) { + $session = get_session('') or die "can't create session"; + $sessionID = $session->id; + C4::Context->_new_userenv($sessionID); + warn "AAA created new session $sessionID"; + } + + $cookie = $query->cookie( + -name => 'CGISESSID', + -value => $session->id, + -HttpOnly => 1 + ); + + if ( $flags = haspermission( $userid, $flagsrequired ) ) { + $loggedin = 1; + } else { + warn "ERROR: haspermission $userid ",dump($flagsrequired); + } my $row = $sth->fetchrow_hashref; + warn "XXX row = ",dump( $row ); - $session->param( $_ => $row->{$_} ) foreach keys %$row; + $session->param( $_ => defined $row->{$_} ? $row->{$_} : '' ) foreach keys %$row; - $session->param('ip', $ENV{'REMOTE_ADDR'}); + $session->param('flags', $flags); + $session->param('ip', $session->remote_addr); $session->param('lasttime',time()); + $session->param( 'interface', $type); + $session->param( 'shibboleth', 1 ); + $session->param( 'sessiontype', '' ); # XXX not 'anon' - $session->param('AuthMemCookie', $token); - C4::Context::set_userenv( - $session->param('number'), $session->param('id'), + C4::Context->set_userenv( + $session->param('number'), $session->param('id'), $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress'), $session->param('branchprinter') + $session->param('emailaddress'), $session->param('branchprinter'), + $session->param('shibboleth') ); -=for removed + C4::Context::set_shelves_userenv( 'bar', $session->param('barshelves') ); + C4::Context::set_shelves_userenv( 'pub', $session->param('pubshelves') ); + C4::Context::set_shelves_userenv( 'tot', $session->param('totshelves') ); + +warn "DEBUG ",dump( $C4::Context::context->{userenv} ); + +=for old-and-unsupported my $row_count = 10; # FIXME:This probably should be a syspref my ($total, $totshelves, $barshelves, $pubshelves); ($barshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(1, $row_count, $session->param('number')); @@ -959,27 +993,26 @@ warn "XXX userid = [$userid] "; C4::Context::set_shelves_userenv('bar',$barshelves); C4::Context::set_shelves_userenv('pub',$pubshelves); C4::Context::set_shelves_userenv('tot',$total); -=cut $loggedin = 1; if ( $type eq 'opac' ) { - my $to = 'https://' . $query->virtual_host . '/' . $query->path_info; + # TODO path_info isn't correct under plack + my $to = 'https://' . $query->virtual_host . '/' . $query->path_info . '?ferweb_login='.time(); warn "XXX redirect $userid to $to"; - ## FIXME 2011-12-20 dpavlin -- redirect logged in users to http print $query->redirect( -uri => $to, -status => 302, -cookie => $cookie ); -# exit; + safe_exit; + warn "FAKE, FALLING THROUGH"; } +=cut } else { - die "Can't find SAML token $token for user $userid\n"; + warn "ERROR: Can't find SAML token $token for user $userid\n"; } - } else { - die "Can't find SAML token for user $userid\n"; - } - - } # XXX SAML anon user + warn "XXX-11 userid = $userid sessionID = $sessionID"; + } + #XXX END OF SAML MODIFICATIONS -- next line is elsif! elsif ( $emailaddress) { # the Google OpenID Connect passes an email address @@ -987,6 +1020,7 @@ warn "XXX userid = [$userid] "; elsif ( $sessionID = $query->cookie("CGISESSID") ) { # assignment, not comparison $session = get_session($sessionID); +warn "XXX-9001 sessionID = $sessionID session =", dump( $session ); C4::Context->_new_userenv($sessionID); my ( $ip, $lasttime, $sessiontype ); my $s_userid = ''; @@ -1023,6 +1057,7 @@ warn "XXX userid = [$userid] "; C4::Context->_unset_userenv($sessionID); $sessionID = undef; $userid = undef; + warn "FLUSH session query id = $q_userid but session id = $s_userid"; } elsif ($logout) { @@ -1032,6 +1067,7 @@ warn "XXX userid = [$userid] "; $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); + warn "FLUSH session logout $sessionID"; #_session_log(sprintf "%20s from %16s logged out at %30s (manually).\n", $userid,$ip,(strftime "%c",localtime)); $sessionID = undef; @@ -1059,6 +1095,7 @@ warn "XXX userid = [$userid] "; #_session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,(strftime "%c",localtime)); $userid = undef; $sessionID = undef; + warn "XXX-LOGOUT lasttime $lasttime"; } elsif ( C4::Context->preference('SessionRestrictionByIP') && $ip ne $ENV{'REMOTE_ADDR'} ) { @@ -1073,8 +1110,10 @@ warn "XXX userid = [$userid] "; #_session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,(strftime "%c",localtime), $info{'newip'}); $sessionID = undef; $userid = undef; + warn "XXX-LOGOUT ip $ip"; } else { + warn "XXX-new-cookie"; $cookie = $query->cookie( -name => 'CGISESSID', -value => $session->id, @@ -1083,6 +1122,7 @@ warn "XXX userid = [$userid] "; $session->param( 'lasttime', time() ); unless ( $sessiontype && $sessiontype eq 'anon' ) { #if this is an anonymous session, we want to update the session, but not behave as if they are logged in... $flags = haspermission( $userid, $flagsrequired ); + warn "XXX flags = ",dump( $flags ); if ($flags) { $loggedin = 1; } else { @@ -1091,7 +1131,10 @@ warn "XXX userid = [$userid] "; } } } + warn "XXX-11 userid = $userid sessionID = $sessionID ", defined $session ? $session->id : ''; + unless ( $userid || $sessionID ) { + warn "XXX-30 userid = $userid sessionID = $sessionID"; #we initiate a session prior to checking for a username to allow for anonymous sessions... my $session = get_session("") or die "Auth ERROR: Cannot get_session()"; @@ -1347,6 +1390,7 @@ warn "XXX userid = [$userid] "; } } # END unless ($userid) + warn "XXX-44 userid = $userid cookie = ",dump( $cookie ), " sessionID = $sessionID loggedin = $loggedin flags = $flags"; # finished authentification, now respond if ( $loggedin || $authnotrequired ) { @@ -1357,10 +1401,13 @@ warn "XXX userid = [$userid] "; -value => '', -HttpOnly => 1 ); + warn "nuke cookie"; } track_login_daily( $userid ); - +warn "XXX session = ",dump($session); +warn "XXX userenv = ",dump( C4::Context->userenv ); + warn "RETURN = ", dump( $userid, $cookie, $sessionID, $flags ); return ( $userid, $cookie, $sessionID, $flags ); }