SAML:
- Manage SOAP relay logout request; - Fix a bug into info.tpl.
This commit is contained in:
parent
1380d89865
commit
423541455b
@ -47,8 +47,18 @@ my ( $skinfile, %templateParams );
|
|||||||
|
|
||||||
if ( $portal->process() ) {
|
if ( $portal->process() ) {
|
||||||
|
|
||||||
# 1.1 Case : there is a message to display
|
# 1.1 Image mode
|
||||||
if ( my $info = $portal->info() ) {
|
if ( $portal->{error} == PE_INFO_OK || $portal->{error} == PE_INFO_KO ) {
|
||||||
|
$skinfile = $skin_dir . '/common/ok.png';
|
||||||
|
if ( $portal->{error} == PE_INFO_KO ) {
|
||||||
|
$skinfile = $skin_dir . '/common/warning.png';
|
||||||
|
}
|
||||||
|
$portal->printImage($skinfile, 'image/png');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 1.2 Case : there is a message to display
|
||||||
|
elsif ( my $info = $portal->info() ) {
|
||||||
$skinfile = 'info.tpl';
|
$skinfile = 'info.tpl';
|
||||||
%templateParams = (
|
%templateParams = (
|
||||||
AUTH_ERROR_TYPE => $portal->error_type,
|
AUTH_ERROR_TYPE => $portal->error_type,
|
||||||
@ -59,7 +69,7 @@ if ( $portal->process() ) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# 1.2 Case : display menu
|
# 1.3 Case : display menu
|
||||||
else {
|
else {
|
||||||
$skinfile = 'menu.tpl';
|
$skinfile = 'menu.tpl';
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
function stop() {
|
function stop() {
|
||||||
_go=0;
|
_go=0;
|
||||||
$('#timer').html("...");
|
$('#timer').html("...");
|
||||||
|
$('#form button[type=submit]').attr('disabled','');
|
||||||
}
|
}
|
||||||
function go() {
|
function go() {
|
||||||
if(_go) {
|
if(_go) {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
function stop() {
|
function stop() {
|
||||||
_go=0;
|
_go=0;
|
||||||
$('#timer').html("...");
|
$('#timer').html("...");
|
||||||
|
$('#form button[type=submit]').attr('disabled','');
|
||||||
}
|
}
|
||||||
function go() {
|
function go() {
|
||||||
if(_go) {
|
if(_go) {
|
||||||
|
@ -55,6 +55,8 @@ sub issuerForUnAuthUser {
|
|||||||
$self->getMetaDataURL( "samlIDPSSODescriptorSingleLogoutServiceHTTP", 2 );
|
$self->getMetaDataURL( "samlIDPSSODescriptorSingleLogoutServiceHTTP", 2 );
|
||||||
my $saml_ars_url = $self->getMetaDataURL(
|
my $saml_ars_url = $self->getMetaDataURL(
|
||||||
"samlIDPSSODescriptorArtifactResolutionServiceArtifact");
|
"samlIDPSSODescriptorArtifactResolutionServiceArtifact");
|
||||||
|
my $saml_slo_url_relay_soap = $self->{portal}
|
||||||
|
. '/saml/relaySingleLogoutSOAP';
|
||||||
|
|
||||||
# Get HTTP request informations to know
|
# Get HTTP request informations to know
|
||||||
# if we are receving SAML request or response
|
# if we are receving SAML request or response
|
||||||
@ -173,15 +175,64 @@ sub issuerForUnAuthUser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 1.3. SLO SOAP replay (send SOAP requests asynchronously)
|
# 1.3. SLO SOAP replay (send SOAP requests asynchronously)
|
||||||
# http://auth.example.com/saml/relaySingleLogoutSOAP
|
|
||||||
my $saml_slo_url_relay_soap =
|
|
||||||
'http://auth.example.com/saml/relaySingleLogoutSOAP';
|
|
||||||
if ( $url =~ /^(\Q$saml_slo_url_relay_soap\E)/i ) {
|
if ( $url =~ /^(\Q$saml_slo_url_relay_soap\E)/i ) {
|
||||||
|
|
||||||
$self->lmLog( "URL $url detected as a relay service URL", 'debug' );
|
$self->lmLog( "URL $url detected as a relay service URL", 'debug' );
|
||||||
|
|
||||||
my $r = $self->param('relay');
|
# Check if relay parameter is present (mandatory)
|
||||||
print STDERR "$r\n";
|
my $samlID;
|
||||||
|
unless ( $samlID = $self->param('relay') ) {
|
||||||
|
$self->lmLog( "No relayID detected", 'error' );
|
||||||
|
return PE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Retrieve the corresponding data from samlStorage
|
||||||
|
my $samlData = $self->replayProtection($samlID);
|
||||||
|
unless ( $samlData && $samlData ne 1 ) {
|
||||||
|
$self->lmLog( "No logout dump found for samlID $samlID", 'error' );
|
||||||
|
return PE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rebuild the logout object
|
||||||
|
my $logout;
|
||||||
|
unless ( $logout = $self->createLogout($server) ) {
|
||||||
|
$self->lmLog( "Could not rebuild logout object",
|
||||||
|
'error' );
|
||||||
|
return PE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load Session and Identity if they exist
|
||||||
|
my $session = $samlData->{_lassoSessionDump};
|
||||||
|
my $identity = $samlData->{_lassoIdentityDump};
|
||||||
|
my $providerID = $samlData->{_providerID};
|
||||||
|
|
||||||
|
if ($session) {
|
||||||
|
unless ( $self->setSessionFromDump( $logout, $session ) ) {
|
||||||
|
$self->lmLog( "Unable to load Lasso Session", 'error' );
|
||||||
|
return PE_ERROR;
|
||||||
|
}
|
||||||
|
$self->lmLog( "Lasso Session loaded", 'debug' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($identity) {
|
||||||
|
unless ( $self->setIdentityFromDump( $logout, $identity ) ) {
|
||||||
|
$self->lmLog( "Unable to load Lasso Identity", 'error' );
|
||||||
|
return PE_ERROR;
|
||||||
|
}
|
||||||
|
$self->lmLog( "Lasso Identity loaded", 'debug' );
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send the logout request
|
||||||
|
my ( $rstatus, $rmethod, $rinfo ) =
|
||||||
|
$self->sendLogoutRequestToServiceProvider(
|
||||||
|
$logout, $providerID, Lasso::Constants::HTTP_METHOD_SOAP );
|
||||||
|
unless ($rstatus) {
|
||||||
|
$self->lmLog( "Fail to process SOAP logout request to $providerID",
|
||||||
|
'error' );
|
||||||
|
return PE_INFO_KO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PE_INFO_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ use constant {
|
|||||||
# Portal errors
|
# Portal errors
|
||||||
# Developers warning, do not use PE_INFO, it's reserved to autoRedirect.
|
# Developers warning, do not use PE_INFO, it's reserved to autoRedirect.
|
||||||
# If you want to send an information, use $self->info('text').
|
# If you want to send an information, use $self->info('text').
|
||||||
|
PE_INFO_KO => -5,
|
||||||
|
PE_INFO_OK => -4,
|
||||||
PE_INFO => -3,
|
PE_INFO => -3,
|
||||||
PE_REDIRECT => -2,
|
PE_REDIRECT => -2,
|
||||||
PE_DONE => -1,
|
PE_DONE => -1,
|
||||||
@ -109,10 +111,10 @@ use constant {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# EXPORTER PARAMETERS
|
# EXPORTER PARAMETERS
|
||||||
our @EXPORT = qw( PE_INFO PE_REDIRECT PE_DONE PE_OK PE_SESSIONEXPIRED
|
our @EXPORT = qw( PE_INFO_KO PE_INFO_OK PE_INFO PE_REDIRECT PE_DONE PE_OK
|
||||||
PE_FORMEMPTY PE_WRONGMANAGERACCOUNT PE_USERNOTFOUND PE_BADCREDENTIALS
|
PE_SESSIONEXPIRED PE_FORMEMPTY PE_WRONGMANAGERACCOUNT PE_USERNOTFOUND
|
||||||
PE_LDAPCONNECTFAILED PE_LDAPERROR PE_APACHESESSIONERROR PE_FIRSTACCESS
|
PE_BADCREDENTIALS PE_LDAPCONNECTFAILED PE_LDAPERROR PE_APACHESESSIONERROR
|
||||||
PE_BADCERTIFICATE PE_PP_ACCOUNT_LOCKED PE_PP_PASSWORD_EXPIRED
|
PE_FIRSTACCESS PE_BADCERTIFICATE PE_PP_ACCOUNT_LOCKED PE_PP_PASSWORD_EXPIRED
|
||||||
PE_CERTIFICATEREQUIRED PE_ERROR PE_PP_CHANGE_AFTER_RESET
|
PE_CERTIFICATEREQUIRED PE_ERROR PE_PP_CHANGE_AFTER_RESET
|
||||||
PE_PP_PASSWORD_MOD_NOT_ALLOWED PE_PP_MUST_SUPPLY_OLD_PASSWORD
|
PE_PP_PASSWORD_MOD_NOT_ALLOWED PE_PP_MUST_SUPPLY_OLD_PASSWORD
|
||||||
PE_PP_INSUFFICIENT_PASSWORD_QUALITY PE_PP_PASSWORD_TOO_SHORT
|
PE_PP_INSUFFICIENT_PASSWORD_QUALITY PE_PP_PASSWORD_TOO_SHORT
|
||||||
@ -787,6 +789,27 @@ sub info {
|
|||||||
return $self->{_info};
|
return $self->{_info};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##@method public void printImage(string file, string type)
|
||||||
|
# Print image to STDOUT
|
||||||
|
# @param $file The path to the file to print
|
||||||
|
# @param $type The content-type to use (ie: image/png)
|
||||||
|
# @return void
|
||||||
|
sub printImage {
|
||||||
|
my ( $self, $file, $type ) = @_;
|
||||||
|
binmode STDOUT;
|
||||||
|
unless (open(IMAGE, '<', $file)) {
|
||||||
|
$self->lmLog( "Could not display image '$file'", 'error' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print $self->header(
|
||||||
|
$type . '; charset=utf-8; content-length=' . (stat($file))[10]);
|
||||||
|
my $buffer = "";
|
||||||
|
while (read(IMAGE, $buffer, 4096)) {
|
||||||
|
print $buffer;
|
||||||
|
}
|
||||||
|
close(IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# MAIN subroutine: call all steps until one returns something #
|
# MAIN subroutine: call all steps until one returns something #
|
||||||
# different than PE_OK #
|
# different than PE_OK #
|
||||||
|
@ -1360,6 +1360,7 @@ sub replayProtection {
|
|||||||
# A session was found
|
# A session was found
|
||||||
foreach (@keys) {
|
foreach (@keys) {
|
||||||
my $session = $_;
|
my $session = $_;
|
||||||
|
my $result = 1;
|
||||||
|
|
||||||
# Delete it
|
# Delete it
|
||||||
eval {
|
eval {
|
||||||
@ -1372,6 +1373,9 @@ sub replayProtection {
|
|||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (defined $h{data}) {
|
||||||
|
$result = $h{data};
|
||||||
|
}
|
||||||
eval { tied(%h)->delete(); };
|
eval { tied(%h)->delete(); };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$self->lmLog(
|
$self->lmLog(
|
||||||
@ -1383,7 +1387,7 @@ sub replayProtection {
|
|||||||
$self->lmLog(
|
$self->lmLog(
|
||||||
"Assertion session $session (Message ID $samlID) was deleted",
|
"Assertion session $session (Message ID $samlID) was deleted",
|
||||||
'debug' );
|
'debug' );
|
||||||
return 1;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2117,10 +2121,16 @@ sub sendLogoutRequestToServiceProvider {
|
|||||||
if ( !$method ) {
|
if ( !$method ) {
|
||||||
$method =
|
$method =
|
||||||
$self->getFirstHttpMethod( $server, $providerID, $protocolType );
|
$self->getFirstHttpMethod( $server, $providerID, $protocolType );
|
||||||
|
|
||||||
#$method = Lasso::Constants::HTTP_METHOD_SOAP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Fix a default value for the relay parameter
|
||||||
|
$relay = 0 unless ( defined $relay );
|
||||||
|
|
||||||
|
# Build the request unless this is a SOAP relay logout request
|
||||||
|
unless ( $method == Lasso::Constants::HTTP_METHOD_SOAP && $relay ) {
|
||||||
|
|
||||||
|
$self->lmLog( "No logout request found, build it", 'debug' );
|
||||||
|
|
||||||
# Initiate the logout request
|
# Initiate the logout request
|
||||||
unless ( $self->initLogoutRequest( $logout, $providerID, $method ) ) {
|
unless ( $self->initLogoutRequest( $logout, $providerID, $method ) ) {
|
||||||
$self->lmLog( "Initiate logout request failed for $providerID",
|
$self->lmLog( "Initiate logout request failed for $providerID",
|
||||||
@ -2134,6 +2144,8 @@ sub sendLogoutRequestToServiceProvider {
|
|||||||
return ( 0, $method, undef );
|
return ( 0, $method, undef );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
# Send logout request to the provider depending of the request method
|
# Send logout request to the provider depending of the request method
|
||||||
# HTTP-REDIRECT
|
# HTTP-REDIRECT
|
||||||
if ( $method == Lasso::Constants::HTTP_METHOD_REDIRECT ) {
|
if ( $method == Lasso::Constants::HTTP_METHOD_REDIRECT ) {
|
||||||
@ -2181,44 +2193,41 @@ sub sendLogoutRequestToServiceProvider {
|
|||||||
# HTTP-SOAP
|
# HTTP-SOAP
|
||||||
if ( $method == Lasso::Constants::HTTP_METHOD_SOAP ) {
|
if ( $method == Lasso::Constants::HTTP_METHOD_SOAP ) {
|
||||||
|
|
||||||
# Fix a default value for the relay parameter
|
|
||||||
$relay = 1 unless ( defined $relay );
|
|
||||||
|
|
||||||
# Build a relay request, to be used after SLO process is done
|
# Build a relay request, to be used after SLO process is done
|
||||||
if ($relay) {
|
if ($relay) {
|
||||||
|
|
||||||
$self->lmLog( "Store SOAP logout request for $providerID",
|
$self->lmLog( "Build SOAP relay logout request for $providerID",
|
||||||
'debug' );
|
'debug' );
|
||||||
|
|
||||||
my $samlID = $logout->request()->ID;
|
|
||||||
my $random = new String::Random;
|
my $random = new String::Random;
|
||||||
my $cookieName =
|
my $samlID = $random->randregex('[a-z0-9]{32}');
|
||||||
$self->{cookieName} . '-r'
|
|
||||||
. $random->randregex('[A-Z]{3}[a-z]{5}.\d{2}');
|
# Build needed information to be stored into samlStorage
|
||||||
|
my $samlData = ();
|
||||||
|
unless ( $logout->get_session() && $logout->get_identity() ) {
|
||||||
|
$self->lmLog(
|
||||||
|
"No session and identity found into logout object",
|
||||||
|
'error' );
|
||||||
|
return ( 0, $method, undef );
|
||||||
|
}
|
||||||
|
$samlData->{_lassoSessionDump} = $logout->get_session->dump;
|
||||||
|
$samlData->{_lassoIdentityDump} = $logout->get_identity->dump;
|
||||||
|
$samlData->{_providerID} = $providerID;
|
||||||
|
|
||||||
# Store information in temporary storage, to be reused then.
|
# Store information in temporary storage, to be reused then.
|
||||||
return ( 0, $method, undef )
|
return ( 0, $method, undef )
|
||||||
unless ( $self->storeReplayProtection( $samlID, $logout->dump ) );
|
unless ( $self->storeReplayProtection( $samlID, $samlData ) );
|
||||||
|
|
||||||
# Build the cookie that will be used to retrieve this SOAP request.
|
$self->lmLog( "Store request for $providerID", 'debug' );
|
||||||
push @{ $self->{cookie} },
|
|
||||||
$self->cookie(
|
|
||||||
-name => $cookieName,
|
|
||||||
-value => $samlID,
|
|
||||||
-expires => '+3m'
|
|
||||||
);
|
|
||||||
|
|
||||||
# Build the URL that could be used to play this logout request
|
# Build the URL that could be used to play this logout request
|
||||||
my $slo_url =
|
my $slo_url = $self->{portal}
|
||||||
'http://auth.example.com/saml/relaySingleLogoutSOAP?relay='
|
. '/saml/relaySingleLogoutSOAP?relay=' . $samlID;
|
||||||
. $cookieName;
|
|
||||||
|
|
||||||
# Display information to the user
|
# Display information to the user
|
||||||
$info .= '<li>'
|
$info .= '<li>'
|
||||||
. $providerName . '...'
|
. $providerName . '... '
|
||||||
. '<img src="'
|
. '<img src="' . $slo_url . '" width="10" height="10" /></li>';
|
||||||
. $slo_url
|
|
||||||
. '" width="0" height="0" /></li>';
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user