SAML in progress (#595)

This commit is contained in:
Xavier Guimard 2016-11-22 20:55:10 +00:00
parent b1f2ac6a73
commit fb741f9bea
7 changed files with 88 additions and 87 deletions

View File

@ -361,6 +361,7 @@ t/90-translations.t
t/99-pod.t
t/lmConf-1.js
t/sessions/lock/.exists
t/sessions/saml/lock/.exists
t/sessions2/6e30af4ffa5689b3e49a104d1b160d316db2b2161a0f45776994eed19dbdc101
t/sessions2/lock/Apache-Session-6e30af4ffa5689b3e49a104d1b160d316db2b2161a0f45776994eed19dbdc101.lock
t/test-lib.pm

View File

@ -60,55 +60,52 @@ sub display {
}
# 1. Good authentication
# 1.1 Image mode
if ( $req->{error} == PE_IMG_OK || $req->{error} == PE_IMG_NOK ) {
$self->lmLog( 'Request for file', 'debug' );
return staticFile( "common/"
. ( $req->{error} == PE_IMG_OK ? 'ok.png' : 'warning.png' ) );
}
# 1.2 Case : there is a message to display
elsif ( my $info = $req->info() ) {
$skinfile = 'info';
%templateParams = (
AUTH_ERROR_TYPE => $req->error_type,
MSG => $info,
URL => $req->{urldc},
HIDDEN_INPUTS => $self->buildHiddenForm(),
ACTIVE_TIMER => $self->conf->{activeTimer},
FORM_METHOD => $self->conf->{infoFormMethod},
);
}
# 1.3 Redirection
elsif ( $req->{error} == PE_REDIRECT ) {
$skinfile = "redirect";
%templateParams = (
URL => $req->{urldc},
HIDDEN_INPUTS => $self->buildHiddenForm($req),
FORM_METHOD => $req->datas->{redirectFormMethod} || 'get',
);
}
# 1.4 Case : display menu
elsif ( $req->error == PE_OK ) {
# 1.1 Image mode
if ( $req->{error} == PE_IMG_OK || $req->{error} == PE_IMG_NOK ) {
$self->lmLog( 'Request for file', 'debug' );
return staticFile( "common/"
. ( $req->{error} == PE_IMG_OK ? 'ok.png' : 'warning.png' ) );
}
$skinfile = 'menu';
# 1.2 Case : there is a message to display
elsif ( my $info = $req->info() ) {
$skinfile = 'info';
%templateParams = (
AUTH_ERROR_TYPE => $req->error_type,
MSG => $info,
URL => $req->{urldc},
HIDDEN_INPUTS => $self->buildHiddenForm(),
ACTIVE_TIMER => $self->conf->{activeTimer},
FORM_METHOD => $self->conf->{infoFormMethod},
);
}
#utf8::decode($auth_user);
# 1.3 Redirection
elsif ( $req->{error} == PE_REDIRECT ) {
$skinfile = "redirect";
%templateParams = (
URL => $req->{urldc},
HIDDEN_INPUTS => $self->buildHiddenForm(),
FORM_METHOD => $req->datas->{redirectFormMethod} || 'get',
);
}
# 1.4 Case : display menu
else {
$skinfile = 'menu';
#utf8::decode($auth_user);
%templateParams = (
AUTH_USER =>
$req->{sessionInfo}->{ $self->conf->{portalUserAttr} },
NEWWINDOW => $self->conf->{portalOpenLinkInNewWindow},
LOGOUT_URL => $self->conf->{portal} . "?logout=1",
APPSLIST_ORDER => $req->{sessionInfo}->{'appsListOrder'},
PING => $self->conf->{portalPingInterval},
$self->menu->params($req),
);
}
%templateParams = (
AUTH_USER => $req->{sessionInfo}->{ $self->conf->{portalUserAttr} },
NEWWINDOW => $self->conf->{portalOpenLinkInNewWindow},
LOGOUT_URL => $self->conf->{portal} . "?logout=1",
APPSLIST_ORDER => $req->{sessionInfo}->{'appsListOrder'},
PING => $self->conf->{portalPingInterval},
$self->menu->params($req),
);
}
# 2. Authentication not complete
@ -120,7 +117,7 @@ sub display {
%templateParams = (
AUTH_ERROR_TYPE => $req->error_type,
NOTIFICATION => $notif,
HIDDEN_INPUTS => $self->buildHiddenForm(),
HIDDEN_INPUTS => $self->buildHiddenForm($req),
AUTH_URL => $req->{datas}->{_url},
CHOICE_PARAM => $self->conf->{authChoiceParam},
CHOICE_VALUE => $req->{_authChoice},
@ -136,7 +133,7 @@ sub display {
AUTH_ERROR_TYPE => $req->error_type,
AUTH_URL => $req->{datas}->{_url},
MSG => $req->info,
HIDDEN_INPUTS => $self->buildHiddenForm(),
HIDDEN_INPUTS => $self->buildHiddenForm($req),
ACTIVE_TIMER => $self->conf->{activeTimer},
FORM_METHOD => $self->conf->{confirmFormMethod},
CHOICE_PARAM => $self->conf->{authChoiceParam},
@ -158,7 +155,7 @@ sub display {
AUTH_ERROR_TYPE => $req->error_type,
MSG => $info,
URL => $req->{urldc},
HIDDEN_INPUTS => $self->buildHiddenForm(),
HIDDEN_INPUTS => $self->buildHiddenForm($req),
ACTIVE_TIMER => $self->conf->{activeTimer},
FORM_METHOD => $self->conf->{infoFormMethod},
CHOICE_PARAM => $self->conf->{authChoiceParam},
@ -201,7 +198,7 @@ sub display {
DISPLAY_REGISTER => $self->conf->{portalDisplayRegister},
MAIL_URL => $self->conf->{mailUrl},
REGISTER_URL => $self->conf->{registerUrl},
HIDDEN_INPUTS => $self->buildHiddenForm(),
HIDDEN_INPUTS => $self->buildHiddenForm($req),
);
# Display captcha if it's enabled
@ -367,16 +364,15 @@ sub staticFile {
}
sub buildHiddenForm {
my ($self) = @_;
my @keys = keys %{ $self->conf->{portalHiddenFormValues} };
my $val = '';
my ( $self, $req ) = @_;
my @keys = keys %{ $req->{portalHiddenFormValues} };
my $val = '';
foreach (@keys) {
# Check XSS attacks
next
if $self->checkXSSAttack( $_,
$self->conf->{portalHiddenFormValues}->{$_} );
if $self->checkXSSAttack( $_, $req->{portalHiddenFormValues}->{$_} );
# Build hidden input HTML code
$val .= qq{<input type="hidden" name="$_" id="$_" value="}

View File

@ -153,7 +153,16 @@ sub do {
}
}
else {
if ( $err and $err != PE_LOGOUT_OK and $err != PE_REDIRECT ) {
if (
$err
and $err != PE_LOGOUT_OK
and (
$err != PE_REDIRECT
or ( $err == PE_REDIRECT
and $req->datas->{redirectFormMethod} eq 'post' )
)
)
{
my ( $tpl, $prms ) = $self->display($req);
return $self->sendHtml( $req, $tpl, params => $prms );
}
@ -488,7 +497,7 @@ sub autoPost {
return PE_INFO;
}
$self->{redirectFormMethod} = "post";
$req->datas->{redirectFormMethod} = "post";
return PE_REDIRECT;
}
@ -563,26 +572,4 @@ sub clearHiddenFormValue {
return;
}
##@method public string buildHiddenForm()
# Return an HTML representation of hidden values.
# @return HTML code
sub buildHiddenForm {
my ( $self, $req ) = @_;
my @keys = keys %{ $req->{portalHiddenFormValues} // {} };
my $val = '';
foreach (@keys) {
# Check XSS attacks
next
if $self->checkXSSAttack( $_, $req->{portalHiddenFormValues}->{$_} );
# Build hidden input HTML code
$val .= qq{<input type="hidden" name="$_" id="$_" value="}
. $req->{portalHiddenFormValues}->{$_} . '" />';
}
return $val;
}
1;

View File

@ -4,7 +4,7 @@ use IO::String;
require 't/test-lib.pm';
my $maintests = 7;
my $maintests = 9;
my $debug = 'debug';
my $res;
my %handlerOR = ( issuer => [], sp => [] );
@ -40,7 +40,7 @@ SKIP: {
defined( $cookies->{lemonldapidp} )
and $cookies->{lemonldapidp} == 0
),
'IDP cookie defined'
'IDP cookie deleted'
)
or explain( $res->[1],
'Set-Cookie => lemonldapidp=0; domain=.sp.com; path=/; expires=-1d' );
@ -63,13 +63,26 @@ SKIP: {
"confirm=$confirm&idp=https://auth.idp.com/saml/metadata"),
accept => 'text/html',
length => length($confirm) + 47,
cookie => 'lemonldapidp=0',
),
'Select IDP'
);
ok( $res->[0] == 200, 'Return code is 200' );
$cookies = $sp->getCookies($res);
ok(
(
defined( $cookies->{lemonldapidp} )
and $cookies->{lemonldapidp} eq 'https://auth.idp.com/saml/metadata'
),
'IDP cookie defined'
)
or explain(
$res->[1],
'Set-Cookie => lemonldapidp=https://auth.idp.com/saml/metadata; domain=.sp.com; path=/'
);
}
count($maintests);
clean_sessions();
done_testing( count() );
sub switch {
@ -346,7 +359,7 @@ sub sp {
samlIDPMetaDataOptions => {
idp => {
samlIDPMetaDataOptionsEncryptionMode => 'none',
samlIDPMetaDataOptionsSSOBinding => 'POST',
samlIDPMetaDataOptionsSSOBinding => 'POST',
}
},
samlIDPMetaDataXML => {

View File

@ -56,8 +56,8 @@
"portal": "http://auth.example.com/",
"samlStorage": "Apache::Session::File",
"samlStorageOptions": {
"Directory": "t/sessions",
"LockDirectory": "t/sessions/lock",
"Directory": "t/sessions/saml",
"LockDirectory": "t/sessions/saml/lock",
"generateModule": "Lemonldap::NG::Common::Apache::Session::Generate::SHA256"
},
"reloadUrls": {},

View File

@ -28,9 +28,13 @@ sub clean_sessions {
foreach ( grep { /^[^\.]/ } readdir(D) ) {
unlink "t/sessions/$_", "t/sessions/lock/Apache-Session-$_.lock";
}
opendir D, 't/sessions/lock' or die $!;
foreach ( grep { /^[^\.]/ } readdir(D) ) {
unlink "t/sessions/lock/$_";
foreach my $dir (qw(t/sessions/lock t/sessions/saml/lock t/sessions/saml)) {
if ( -d $dir ) {
opendir D, $dir or die $!;
foreach ( grep { /^[^\.]/ } readdir(D) ) {
unlink "$dir/$_";
}
}
}
}