Change session key names between Auth and Issuer (SAML #1468)

This commit is contained in:
Xavier Guimard 2018-06-29 06:50:31 +02:00
parent 73f66df1e2
commit e6ad687618
4 changed files with 97 additions and 44 deletions

View File

@ -32,6 +32,9 @@ has ssoAssConsumerRe => ( is => 'rw' );
has sloRe => ( is => 'rw' ); has sloRe => ( is => 'rw' );
has artRe => ( is => 'rw' ); has artRe => ( is => 'rw' );
has catch => ( is => 'rw' ); has catch => ( is => 'rw' );
use constant sessionKind => 'SAML';
use constant lsDump => '_lassoSessionDump';
use constant liDump => '_lassoIdentityDump';
sub forAuthUser { 'handleAuthRequests' } sub forAuthUser { 'handleAuthRequests' }
@ -322,7 +325,13 @@ sub extractFormInfo {
Lemonldap::NG::Common::Apache::Session->searchOn( Lemonldap::NG::Common::Apache::Session->searchOn(
$self->amOpts, "ProxyID", $assertion_responded ); $self->amOpts, "ProxyID", $assertion_responded );
if ( my @saml_sessions_keys = keys %$saml_sessions ) { if (
my @saml_sessions_keys = grep {
$saml_sessions->{$_}->{_session_kind} eq
$self->sessionKind
} keys %$saml_sessions
)
{
# Warning if more than one session found # Warning if more than one session found
if ( $#saml_sessions_keys > 0 ) { if ( $#saml_sessions_keys > 0 ) {
@ -562,7 +571,12 @@ sub extractFormInfo {
Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts, Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts,
"_nameID", $name_id->dump ); "_nameID", $name_id->dump );
if ( my @local_sessions_keys = keys %$local_sessions ) { if (
my @local_sessions_keys = grep {
$local_sessions->{$_}->{_session_kind} eq $self->sessionKind
} keys %$local_sessions
)
{
# At least one session was found # At least one session was found
foreach (@local_sessions_keys) { foreach (@local_sessions_keys) {
@ -602,13 +616,13 @@ sub extractFormInfo {
# Get Lasso::Session dump # Get Lasso::Session dump
# This value is erased if a next session match the SLO request # This value is erased if a next session match the SLO request
if ( $ssoSession if ( $ssoSession
&& $ssoSession->data->{_lassoSessionDump} ) && $ssoSession->data->{ $self->lsDump } )
{ {
$self->logger->debug( $self->logger->debug(
"Get Lasso::Session dump from session $real_session" "Get Lasso::Session dump from session $real_session"
); );
$session_dump = $session_dump =
$ssoSession->data->{_lassoSessionDump}; $ssoSession->data->{ $self->lsDump };
} }
# Real session will be deleted after (see $req->steps... before) # Real session will be deleted after (see $req->steps... before)
@ -1149,8 +1163,8 @@ sub setAuthSessionInfo {
my $identity = $login->get_identity; my $identity = $login->get_identity;
# Dump Lasso objects in session # Dump Lasso objects in session
$req->{sessionInfo}->{_lassoSessionDump} = $session->dump() if $session; $req->{sessionInfo}->{ $self->lsDump } = $session->dump() if $session;
$req->{sessionInfo}->{_lassoIdentityDump} = $identity->dump() if $identity; $req->{sessionInfo}->{ $self->liDump } = $identity->dump() if $identity;
# Keep SAML Token in session # Keep SAML Token in session
my $store_samlToken = $self->conf->{samlIDPMetaDataOptions}->{$idpConfKey} my $store_samlToken = $self->conf->{samlIDPMetaDataOptions}->{$idpConfKey}
@ -1217,7 +1231,7 @@ sub authLogout {
$self->deleteSAMLSecondarySessions($session_id); $self->deleteSAMLSecondarySessions($session_id);
# Recover Lasso::Session dump # Recover Lasso::Session dump
my $session_dump = $req->{sessionInfo}->{_lassoSessionDump}; my $session_dump = $req->{sessionInfo}->{ $self->lsDump };
unless ($session_dump) { unless ($session_dump) {
$self->userLogger->error("Could not get session dump from session"); $self->userLogger->error("Could not get session dump from session");

View File

@ -25,6 +25,9 @@ has ssoUrlRe => ( is => 'rw' );
has ssoUrlArtifact => ( is => 'rw' ); has ssoUrlArtifact => ( is => 'rw' );
has ssoGetUrl => ( is => 'rw' ); has ssoGetUrl => ( is => 'rw' );
use constant sessionKind => 'ISAML';
use constant lsDump => '_lassoSessionDumpI';
use constant liDump => '_lassoIdentityDumpI';
# INTERFACE # INTERFACE
@ -220,8 +223,8 @@ sub run {
if ( $request or $idp_initiated ) { if ( $request or $idp_initiated ) {
# Load Session and Identity if they exist # Load Session and Identity if they exist
my $session = $req->{sessionInfo}->{_lassoSessionDump}; my $session = $req->{sessionInfo}->{ $self->lsDump };
my $identity = $req->{sessionInfo}->{_lassoIdentityDump}; my $identity = $req->{sessionInfo}->{ $self->liDump };
if ($session) { if ($session) {
unless ( $self->setSessionFromDump( $login, $session ) ) { unless ( $self->setSessionFromDump( $login, $session ) ) {
@ -812,14 +815,14 @@ sub run {
# Update session # Update session
$self->logger->debug("Save Lasso identity in session"); $self->logger->debug("Save Lasso identity in session");
$self->updatePersistentSession( $req, $self->updatePersistentSession( $req,
{ _lassoIdentityDump => $login->get_identity->dump }, { $self->liDump => $login->get_identity->dump },
undef, $session_id ); undef, $session_id );
} }
if ( $login->is_session_dirty ) { if ( $login->is_session_dirty ) {
$self->logger->debug("Save Lasso session in session"); $self->logger->debug("Save Lasso session in session");
$self->p->updateSession( $req, $self->p->updateSession( $req,
{ _lassoSessionDump => $login->get_session->dump }, { $self->lsDump => $login->get_session->dump },
$session_id ); $session_id );
} }
@ -1109,8 +1112,8 @@ sub soapSloServer {
} }
# Load Session and Identity if they exist # Load Session and Identity if they exist
my $session = $local_session->data->{_lassoSessionDump}; my $session = $local_session->data->{ $self->lsDump };
my $identity = $local_session->data->{_lassoIdentityDump}; my $identity = $local_session->data->{ $self->liDump };
if ($session) { if ($session) {
unless ( $self->setSessionFromDump( $logout, $session ) ) { unless ( $self->setSessionFromDump( $logout, $session ) ) {
@ -1220,8 +1223,8 @@ sub logout {
my $logout = $self->createLogout( $self->lassoServer ); my $logout = $self->createLogout( $self->lassoServer );
# Load Session and Identity if they exist # Load Session and Identity if they exist
my $session = $req->{sessionInfo}->{_lassoSessionDump}; my $session = $req->{sessionInfo}->{ $self->lsDump };
my $identity = $req->{sessionInfo}->{_lassoIdentityDump}; my $identity = $req->{sessionInfo}->{ $self->liDump };
if ($session) { if ($session) {
unless ( $self->setSessionFromDump( $logout, $session ) ) { unless ( $self->setSessionFromDump( $logout, $session ) ) {
@ -1288,8 +1291,8 @@ sub sloRelaySoap {
} }
# Load Session and Identity if they exist # Load Session and Identity if they exist
my $session = $relayInfos->data->{_lassoSessionDump}; my $session = $relayInfos->data->{ $self->lsDump };
my $identity = $relayInfos->data->{_lassoIdentityDump}; my $identity = $relayInfos->data->{ $self->liDump };
my $providerID = $relayInfos->data->{_providerID}; my $providerID = $relayInfos->data->{_providerID};
my $relayState = $relayInfos->data->{_relayState} // ''; my $relayState = $relayInfos->data->{_relayState} // '';
my $spConfKey = $self->spList->{$providerID}->{confKey}; my $spConfKey = $self->spList->{$providerID}->{confKey};
@ -1458,8 +1461,8 @@ sub sloServer {
"Get session id $local_session_id (from cookie)"); "Get session id $local_session_id (from cookie)");
} }
if ( $req->{sessionInfo} ) { if ( $req->{sessionInfo} ) {
$session = $req->{sessionInfo}->{_lassoSessionDump}; $session = $req->{sessionInfo}->{ $self->lsDump };
$identity = $req->{sessionInfo}->{_lassoIdentityDump}; $identity = $req->{sessionInfo}->{ $self->liDump };
} }
unless ($session) { unless ($session) {
@ -1472,8 +1475,8 @@ sub sloServer {
} }
# Load Session and Identity if they exist # Load Session and Identity if they exist
$session = $local_session->data->{_lassoSessionDump}; $session = $local_session->data->{ $self->lsDump };
$identity = $local_session->data->{_lassoIdentityDump}; $identity = $local_session->data->{ $self->liDump };
# Import user datas in $req (for other "logout" subs) # Import user datas in $req (for other "logout" subs)
$req->id( $local_session->data->{_session_id} ); $req->id( $local_session->data->{_session_id} );
@ -1665,7 +1668,12 @@ sub attributeServer {
Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts, Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts,
"_nameID", $name_id->dump ); "_nameID", $name_id->dump );
if ( my @saml_sessions_keys = keys %$saml_sessions ) { if (
my @saml_sessions_keys =
grep { $saml_sessions->{$_}->{_session_kind} eq $self->sessionKind }
keys %$saml_sessions
)
{
# Warning if more than one session found # Warning if more than one session found
if ( $#saml_sessions_keys > 0 ) { if ( $#saml_sessions_keys > 0 ) {

View File

@ -1656,10 +1656,17 @@ sub replayProtection {
Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts, Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts,
"_assert_id", $samlID ); "_assert_id", $samlID );
if ( my @keys = keys %$sessions ) { if (
my @keys =
grep { $sessions->{$_}->{_session_kind} eq $self->sessionKind }
keys %$sessions
)
{
# A session was found # A session was found
foreach (@keys) { foreach (@keys) {
next
unless ( $sessions->{$_}->{_session_kind} eq $self->sessionKind );
my $session = $_; my $session = $_;
my $result = 1; my $result = 1;
@ -1780,7 +1787,12 @@ sub loadArtifact {
Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts, Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts,
"_art_id", $id ); "_art_id", $id );
if ( my @keys = keys %$sessions ) { if (
my @keys =
grep { $sessions->{$_}->{_session_kind} eq $self->sessionKind }
keys %$sessions
)
{
my $nb_sessions = $#keys + 1; my $nb_sessions = $#keys + 1;
@ -1852,7 +1864,7 @@ sub createArtifactResponse {
return; return;
} }
my $lassoSession = $session->data->{_lassoSessionDump}; my $lassoSession = $session->data->{ $self->lsDump };
if ($lassoSession) { if ($lassoSession) {
unless ( $self->setSessionFromDump( $login, $lassoSession ) ) { unless ( $self->setSessionFromDump( $login, $lassoSession ) ) {
@ -1880,7 +1892,7 @@ sub createArtifactResponse {
if ( $session_id and $login->is_session_dirty ) { if ( $session_id and $login->is_session_dirty ) {
$self->logger->debug("Save Lasso session in session"); $self->logger->debug("Save Lasso session in session");
$self->updateSession( $req, $self->updateSession( $req,
{ _lassoSessionDump => $login->get_session->dump }, $session_id ); { $self->lsDump => $login->get_session->dump }, $session_id );
} }
# Return artifact message # Return artifact message
@ -2574,14 +2586,12 @@ sub sendLogoutRequestToProvider {
"Build SOAP relay logout request for $providerID"); "Build SOAP relay logout request for $providerID");
my $infos; my $infos;
$infos->{type} = 'relay'; $infos->{type} = 'relay';
$infos->{_utime} = time; $infos->{_utime} = time;
$infos->{_lassoSessionDump} = $infos->{ $self->lsDump } = $req->sessionInfo->{ $self->lsDump };
$req->sessionInfo->{_lassoSessionDump}; $infos->{ $self->liDump } = $req->sessionInfo->{ $self->liDump };
$infos->{_lassoIdentityDump} = $infos->{_providerID} = $providerID;
$req->sessionInfo->{_lassoIdentityDump}; $infos->{_relayState} = $logout->msg_relayState;
$infos->{_providerID} = $providerID;
$infos->{_relayState} = $logout->msg_relayState;
# Create a new relay session # Create a new relay session
my $relayInfos = $self->getSamlSession( undef, $infos ); my $relayInfos = $self->getSamlSession( undef, $infos );
@ -2805,7 +2815,7 @@ sub getSamlSession {
cacheModule => $self->conf->{localSessionStorage}, cacheModule => $self->conf->{localSessionStorage},
cacheModuleOptions => $self->conf->{localSessionStorageOptions}, cacheModuleOptions => $self->conf->{localSessionStorageOptions},
id => $id, id => $id,
kind => "SAML", kind => $self->sessionKind,
( $info ? ( info => $info ) : () ), ( $info ? ( info => $info ) : () ),
} }
); );
@ -2944,7 +2954,12 @@ sub deleteSAMLSecondarySessions {
Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts, Lemonldap::NG::Common::Apache::Session->searchOn( $self->amOpts,
"_saml_id", $session_id ); "_saml_id", $session_id );
if ( my @saml_sessions_keys = keys %$saml_sessions ) { if (
my @saml_sessions_keys =
grep { $saml_sessions->{$_}->{_session_kind} eq $self->sessionKind }
keys %$saml_sessions
)
{
foreach my $saml_session (@saml_sessions_keys) { foreach my $saml_session (@saml_sessions_keys) {

View File

@ -10,7 +10,7 @@ BEGIN {
require 't/saml-lib.pm'; require 't/saml-lib.pm';
} }
my $maintests = 20; my $maintests = 18;
my $debug = 'error'; my $debug = 'error';
my ( $issuer, $sp, $res ); my ( $issuer, $sp, $res );
my %handlerOR = ( issuer => [], sp => [] ); my %handlerOR = ( issuer => [], sp => [] );
@ -125,14 +125,16 @@ SKIP: {
); );
# Verify authentication on SP # Verify authentication on SP
($url,$s) = expectRedirection( $res, qr#^http://auth.sp.com(/?[^\?]*)(?:\?(.*))?$# ); ( $url, $s ) =
expectRedirection( $res, qr#^http://auth.sp.com(/?[^\?]*)(?:\?(.*))?$# );
my $spId = expectCookie($res); my $spId = expectCookie($res);
ok( ok(
$res = $sp->_get( $res = $sp->_get(
$url || '/', $url || '/',
query => $s, query => $s,
cookie => "lemonldapidp=http://auth.idp.com/saml/metadata; lemonldap=$spId", cookie =>
"lemonldapidp=http://auth.idp.com/saml/metadata; lemonldap=$spId",
accept => 'text/html', accept => 'text/html',
), ),
' Follow redirection' ' Follow redirection'
@ -149,11 +151,12 @@ SKIP: {
), ),
'Query SP for logout' 'Query SP for logout'
); );
#( $host, $url, $s ) = ( $host, $url, $s ) =
# expectAutoPost( $res, 'auth.idp.com', '/saml/singleLogout', expectAutoPost( $res, 'auth.idp.com', '/saml/singleLogout',
# 'SAMLRequest' ); 'SAMLRequest' );
#print STDERR Dumper($res); #print STDERR Dumper($res);
skip 'todo', 8; #skip 'todo', 8;
# Push SAML logout request to IdP # Push SAML logout request to IdP
switch ('issuer'); switch ('issuer');
@ -182,7 +185,20 @@ SKIP: {
), ),
'Post SAML response to SP' 'Post SAML response to SP'
); );
expectRedirection( $res, 'http://auth.sp.com' ); ( $url, $s ) =
expectRedirection( $res, qr#^http://auth.sp.com(/.*?)(?:\?(.*))?$# );
# Follow redirection
ok(
$res = $sp->_get(
$url,
query => $s,
accept => 'text/html',
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
),
' Follow redirection'
);
diag "TODO: there is a loop here: http://auth.sp.com$url?$s";
# Test if logout is done # Test if logout is done
switch ('issuer'); switch ('issuer');