SAML in (big) progress (#595)

This commit is contained in:
Xavier Guimard 2016-12-15 21:22:15 +00:00
parent a829958d3d
commit b57d76c0ce
7 changed files with 85 additions and 27 deletions

View File

@ -875,7 +875,7 @@ sub extractFormInfo {
. $req->param("url") . "\" />" . $req->param("url") . "\" />"
. "<input type=\"hidden\" name=\"idp\" value=\"$idp\" />\n"; . "<input type=\"hidden\" name=\"idp\" value=\"$idp\" />\n";
$self->info($html); $self->info( $req, $html );
$req->datas->{login} = 1; $req->datas->{login} = 1;
return PE_CONFIRM; return PE_CONFIRM;
@ -1282,7 +1282,7 @@ sub authLogout {
# Set signature # Set signature
my $signSLOMessage = my $signSLOMessage =
$self->conf->{samlIDPMetaDataOptions}->{$idpConfKey} $self->conf->{samlIDPMetaDataOptions}->{$idpConfKey}
->{samlIDPMetaDataOptionsSignSLOMessage}; ->{samlIDPMetaDataOptionsSignSLOMessage} // 0;
# Build Logout Request # Build Logout Request
my $logout = my $logout =

View File

@ -884,7 +884,7 @@ sub run {
# TODO: replace this # TODO: replace this
#$self->info( "<h3>" . $self->msg(PM_CDC_WRITER) . "</h3>" ); #$self->info( "<h3>" . $self->msg(PM_CDC_WRITER) . "</h3>" );
$self->info($cdc_iframe); $self->info( $req, $cdc_iframe );
} }
# HTTP-REDIRECT # HTTP-REDIRECT
@ -1083,7 +1083,7 @@ sub run {
# Prepare logout on all others SP # Prepare logout on all others SP
my $provider_nb = my $provider_nb =
$self->sendLogoutRequestToProviders( $logout, $relayID ); $self->sendLogoutRequestToProviders( $req, $logout, $relayID );
# Decrypt session index # Decrypt session index
my $local_session_id = my $local_session_id =
@ -1123,18 +1123,8 @@ sub run {
# If no waiting SP, return directly SLO response # If no waiting SP, return directly SLO response
unless ($provider_nb) { unless ($provider_nb) {
if ( return $self->sendLogoutResponseToServiceProvider( $req,
my $tmp = $self->sendLogoutResponseToServiceProvider( $logout, $method );
$logout, $method
)
)
{
return $tmp;
}
else {
$self->lmLog( "Fail to send SLO response", 'error' );
return $self->sendSLOErrorResponse( $logout, $method );
}
} }
# Else build SLO status relay URL and display info # Else build SLO status relay URL and display info
@ -1463,8 +1453,8 @@ sub logout {
# providers during HTTP-REDIRECT process, return PE_INFO to notify to wait # providers during HTTP-REDIRECT process, return PE_INFO to notify to wait
# for them. # for them.
# Redirect on logout page when all is done. # Redirect on logout page when all is done.
if ( $self->sendLogoutRequestToProviders($logout) ) { if ( $self->sendLogoutRequestToProviders( $req, $logout ) ) {
$self->{urldc} = $ENV{SCRIPT_NAME} . "?logout=1"; $self->{urldc} = $req->scriptname . "?logout=1";
return PE_INFO; return PE_INFO;
} }

View File

@ -2309,7 +2309,6 @@ sub sendLogoutResponseToServiceProvider {
$self->lmLog( "Redirect user to $slo_url", 'debug' ); $self->lmLog( "Redirect user to $slo_url", 'debug' );
die 'TODO: autoRedirect must not be called now';
return PE_REDIRECT; return PE_REDIRECT;
} }
@ -2323,13 +2322,12 @@ sub sendLogoutResponseToServiceProvider {
# TODO: insert postUrl in $req # TODO: insert postUrl in $req
$req->postUrl($slo_url); $req->postUrl($slo_url);
$req->datas->{postFields} = { 'SAMLResponse' => $slo_body }; $req->{postFields} = { 'SAMLResponse' => $slo_body };
# RelayState # RelayState
$req->datas->{postFields}->{'RelayState'} = $relaystate $req->{postFields}->{'RelayState'} = $relaystate
if ($relaystate); if ($relaystate);
die 'autoPost must not be called here';
$req->steps( ['autoPost'] ); $req->steps( ['autoPost'] );
return PE_OK; return PE_OK;
} }
@ -2644,7 +2642,7 @@ sub sendLogoutRequestToProviders {
$info .= '</table>'; $info .= '</table>';
# Print some information to the user. # Print some information to the user.
$self->info($info) if $providersCount; $self->p->info( $req, $info ) if $providersCount;
return $providersCount; return $providersCount;
} }

View File

@ -582,4 +582,9 @@ sub getFirstValue {
return $values[0]; return $values[0];
} }
sub info {
my($self,$req,$info)=@_;
print STDERR "####### TODO: info()\n";
}
1; 1;

View File

@ -447,6 +447,7 @@ sub sp {
samlIDPMetaDataOptionsEncryptionMode => 'none', samlIDPMetaDataOptionsEncryptionMode => 'none',
samlIDPMetaDataOptionsSSOBinding => 'POST', samlIDPMetaDataOptionsSSOBinding => 'POST',
samlIDPMetaDataOptionsSLOBinding => 'POST', samlIDPMetaDataOptionsSLOBinding => 'POST',
samlIDPMetaDataOptionsSignSLOMessage => 0,
samlIDPMetaDataOptionsAllowLoginFromIDP => 1, samlIDPMetaDataOptionsAllowLoginFromIDP => 1,
} }
}, },

View File

@ -7,8 +7,8 @@ BEGIN {
require 't/test-lib.pm'; require 't/test-lib.pm';
} }
my $maintests = 33; my $maintests = 39;
my $debug = 'debug'; my $debug = 'error';
my ( $issuer, $sp, $res ); my ( $issuer, $sp, $res );
my %handlerOR = ( issuer => [], sp => [] ); my %handlerOR = ( issuer => [], sp => [] );
@ -222,6 +222,40 @@ SKIP: {
); );
ok( $res->[0] == 200, 'Return code is 200' ); ok( $res->[0] == 200, 'Return code is 200' );
# Get SAML response
ok(
$res->[2]->[0] =~
/<input type="hidden".+?name="SAMLResponse".+?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 response seems valid' )
or explain( decode_base64($samlReq), '<saml ...' );
ok(
$res->[2]->[0] =~ m#<form id="form" action="http://auth.sp.com(.*?)"#s,
'Found IdP URL'
);
$url = $1;
# Post SAML response to SP
$s = "SAMLResponse=$samlReq";
switch ('sp');
ok(
$res = $sp->_post(
$url, IO::String->new($s),
accept => 'text/html',
length => length($s),
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
),
'Post SAML response to SP'
);
ok( $res->[0] == 302, 'Get redirection' );
ok( $sp->getRedirection($res) eq 'http://auth.sp.com', 'Redirection points to SP');
#print STDERR Dumper($res); #print STDERR Dumper($res);
} }

View File

@ -7,8 +7,8 @@ BEGIN {
require 't/test-lib.pm'; require 't/test-lib.pm';
} }
my $maintests = 32; my $maintests = 37;
my $debug = 'debug'; my $debug = 'error';
my ( $issuer, $sp, $res ); my ( $issuer, $sp, $res );
my %handlerOR = ( issuer => [], sp => [] ); my %handlerOR = ( issuer => [], sp => [] );
@ -209,6 +209,36 @@ SKIP: {
), ),
'Launch SAML logout request to IdP' 'Launch SAML logout request to IdP'
); );
ok( $res->[0] == 302, 'Return code is 302' );
ok( $url = $sp->getRedirection($res), 'Get location header' )
or explain(
$res->[1],
'Location: http://auth.sp.com/saml/proxySingleLogoutReturn?SAMLResponse=...'
);
ok(
$url =~
m#^http://auth.sp.com/saml/proxySingleLogoutReturn\?SAMLResponse=(.+)#,
'Redirection points to SP with SAML response'
)
or explain(
$res->[1],
'Location: http://auth.sp.com/saml/proxySingleLogoutReturn?SAMLResponse=...'
);
$url =~ m#^http://auth.sp.com(.+?)\?(.+)$#;
$url = $1;
$query = $2;
# Send SAML response to SP
switch ('sp');
ok(
$res = $sp->_get(
$url,
query => $query,
accept => 'text/html',
),
'Launch SAML logout request to IdP'
);
ok( $res->[0] == 200, 'Return code is 200' ) or explain( $res->[0], 200 );
#print STDERR Dumper($res); #print STDERR Dumper($res);
} }