SAML SLO in progress (#595)

This commit is contained in:
Xavier Guimard 2016-12-09 10:25:05 +00:00
parent 76dffd04b2
commit a959d77e1c
4 changed files with 74 additions and 14 deletions

View File

@ -1285,8 +1285,8 @@ sub authLogout {
# Build Logout Request
my $logout =
$self->createLogoutRequest( $self->lassoServer, $session_dump, $method,
$signSLOMessage );
$self->createLogoutRequest( $req, $self->lassoServer, $session_dump,
$method, $signSLOMessage );
unless ($logout) {
$self->lmLog( "Could not create logout request", 'error' );
return PE_SAML_SLO_ERROR;
@ -1322,13 +1322,14 @@ sub authLogout {
my $slo_body = $logout->msg_body;
$req->postUrl($slo_url);
$self->postFields( { 'SAMLRequest' => $slo_body } );
$req->postFields( { 'SAMLRequest' => $slo_body } );
# RelayState
$self->postFields->{'RelayState'} = $logout->msg_relayState
if ( $logout->msg_relayState );
# Post done in Portal/Simple.pm
$req->steps( ['autoPost'] );
return PE_OK;
}

View File

@ -13,6 +13,11 @@ use POSIX qw(strftime); # Convert SAML2 date into timestamp
use Time::Local; # Convert SAML2 date into timestamp
use Encode; # Encode attribute values
use URI; # Get metadata URL path
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_REDIRECT
PE_SAML_SLO_ERROR
);
our $VERSION = '2.0.0';
@ -2289,7 +2294,7 @@ sub sendLogoutResponseToServiceProvider {
# Logout response
unless ( $self->buildLogoutResponseMsg($logout) ) {
$self->lmLog( "Unable to build SLO response", 'error' );
return 0;
return PE_SAML_SLO_ERROR;
}
# Send response depending on request method
@ -2303,7 +2308,7 @@ sub sendLogoutResponseToServiceProvider {
$self->lmLog( "Redirect user to $slo_url", 'debug' );
die 'TODO: autoRedirect must not be called now';
return $self->autoRedirect;
return PE_REDIRECT;
}
# HTTP-POST
@ -2323,7 +2328,8 @@ sub sendLogoutResponseToServiceProvider {
if ($relaystate);
die 'autoPost must not be called here';
return $self->autoPost;
$req->steps(['autoPost']);
return PE_OK;
}
# HTTP-SOAP
@ -2340,7 +2346,7 @@ sub sendLogoutResponseToServiceProvider {
# If we are here, there was a problem with SOAP response
$self->lmLog( "Logout response was not sent trough SOAP", 'error' );
return 0;
return PE_SAML_SLO_ERROR;
}
@ -2945,8 +2951,7 @@ sub sendSLOErrorResponse {
unless ( $self->setSessionFromDump( $logout, $session ) ) {
$self->lmLog( "Could not set empty session in logout object", 'error' );
die 'Replace this';
$self->quit();
return PE_SAML_SLO_ERROR;
}
# Send unvalidated SLO response

View File

@ -36,7 +36,8 @@ sub init {
$path =~ s/^.*?(\w+).*?$/$1/;
$self->addUnauthRoute( $path => '_redirect', ['GET'] );
$self->addUnauthRoute( $path => '_pRedirect', ['POST'] );
$self->addAuthRoute( $path => "_forAuthUser", [ 'GET', 'POST' ] );
$self->addAuthRoute( $path => "_forAuthUser", ['GET'] );
$self->addAuthRoute( $path => "_pForAuthUser", ['POST'] );
}
else {
$self->lmLog( "No path declared for issuer $type. Skipping", 'debug' );
@ -53,8 +54,8 @@ sub _redirect {
foreach my $k ( keys %$prms ) {
$self->p->setHiddenFormValue( $req, $k, $prms->{$k}, '', 0 );
}
$self->p->setHiddenFormValue( $req, 'issuerMethod', $req->method, '', 0);
$self->p->setHiddenFormValue( $req, 'issuerQuery', $req->query, '', 0);
$self->p->setHiddenFormValue( $req, 'issuerMethod', $req->method, '', 0 );
$self->p->setHiddenFormValue( $req, 'issuerQuery', $req->query, '', 0 );
$req->{urldc} =
$self->conf->{portal}
. $req->path
@ -79,6 +80,7 @@ sub _redirect {
sub _pRedirect {
my ( $self, $req ) = @_;
$self->lmLog( 'Parsing posted datas', 'debug' );
$req->parseBody;
return $self->_redirect($req);
}
@ -99,4 +101,11 @@ sub _forAuthUser {
);
}
sub _pForAuthUser {
my ( $self, $req ) = @_;
$self->lmLog( 'Parsing posted datas', 'debug' );
$req->parseBody;
return $self->_forAuthUser($req);
}
1;

View File

@ -7,8 +7,8 @@ BEGIN {
require 't/test-lib.pm';
}
my $maintests = 26;
my $debug = 'error';
my $maintests = 33;
my $debug = 'debug';
my $res;
my %handlerOR = ( issuer => [], sp => [] );
@ -178,6 +178,50 @@ SKIP: {
'User is identified as dwho@badwolf.org@idp'
) or explain( $res->[1], 'Lm-Remote-User: dwho@badwolf.org@idp' );
# Logout initiated by SP
ok(
$res = $sp->_get(
'/',
query => 'logout',
cookie => "lemonldap=$spId",
accept => 'text/html'
),
'Query SP for logout'
);
ok( $res->[0] == 200, 'Return code is 200' );
ok(
$res->[2]->[0] =~
/<input type="hidden".+?name="SAMLRequest".+?value="(.+?)"/s,
'Found SAML request'
)
or explain(
$res->[2],
' <input type="hidden" name="SAMLRequest" id="SAMLRequest" value="...'
);
$samlReq = $1;
ok( decode_base64($samlReq) =~ /^</s, 'SAML request seems valid' )
or explain( decode_base64($samlReq), '<saml ...' );
ok(
$res->[2]->[0] =~ m#<form id="form" action="http://auth.idp.com(.*?)"#s,
'Found IdP URL'
);
$url = $1;
# Push SAML logout request to IdP
switch ('issuer');
$s = "SAMLRequest=$samlReq";
ok(
$res = $issuer->_post(
$url,
IO::String->new($s),
accept => 'text/html',
cookie => "lemonldap=$idpId",
length => length($s)
),
'Post SAML request to IdP'
);
ok( $res->[0] == 200, 'Return code is 200' );
#print STDERR Dumper($res);
}
@ -515,6 +559,7 @@ sub sp {
idp => {
samlIDPMetaDataOptionsEncryptionMode => 'none',
samlIDPMetaDataOptionsSSOBinding => 'POST',
samlIDPMetaDataOptionsSLOBinding => 'POST',
}
},
samlIDPMetaDataXML => {