Move Ajax hook from handler to portal (Closes: #790)

This commit is contained in:
Xavier Guimard 2016-01-28 22:25:46 +00:00
parent 75a175a9b0
commit b6f7b2a96a
10 changed files with 55 additions and 39 deletions

6
debian/NEWS vendored
View File

@ -19,9 +19,9 @@ lemonldap-ng (1.9.0-1) UNRELEASED; urgency=low
* manager server
To request for authentication, handlers sent a 302 HTTP code even if request
was an Ajax one. From now, a 401 code will be send with a WWW-Authenticate
header containing portal URL. This is a little HTTP protocol hook created
because browsers follow redirection tranparently.
was an Ajax one. From now, after redirection, portal will send a 401 code
with a WWW-Authenticate header containing "SSO portal-URL". This is a little
HTTP protocol hook created because browsers follow redirection tranparently.
If you want to keep old behaviour, set noAjaxHook to 1 (in General Parameters
-> Advanced -> Handler redirections -> Keep redirections for Ajax).

View File

@ -13,4 +13,4 @@ describe('Lemonldap::NG', function() {
browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
});
});
});
});

View File

@ -8,4 +8,4 @@ describe('Lemonldap::NG auth mechanism', function() {
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/?logout=1');
});
});
});

View File

@ -16,4 +16,4 @@ exports.config = {
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};
};

View File

@ -136,33 +136,17 @@ sub goToPortal {
my ( $class, $url, $arg ) = @_;
my ( $ret, $msg );
my $urlc_init = $class->encodeUrl($url);
if ( !$tsv->{noAjaxHook}
and Lemonldap::NG::Handler::API->header_in('Accept') =~
m|application/json| )
{
$msg =
"Ajax request, send 401 instead of 302 "
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Redirect "
. Lemonldap::NG::Handler::API->remote_ip
. " to portal (url was $url)";
Lemonldap::NG::Handler::API->set_header_out(
'WWW-Authenticate' => &{ $tsv->{portal} }()
. "?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
$ret = HTTP_UNAUTHORIZED;
}
else {
$msg =
"Redirect "
. Lemonldap::NG::Handler::API->remote_ip
. " to portal (url was $url)";
Lemonldap::NG::Handler::API->set_header_out(
'Location' => &{ $tsv->{portal} }()
. "?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
$ret = REDIRECT;
}
Lemonldap::NG::Handler::Main::Logger->lmLog( $msg, 'debug' );
return $ret;
. " to portal (url was $url)",
'debug'
);
Lemonldap::NG::Handler::API->set_header_out(
'Location' => &{ $tsv->{portal} }()
. "?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
return REDIRECT;
}
## @rmethod protected $ fetchId()
@ -580,8 +564,8 @@ sub redirectFilter {
}
while ( $f->read( my $buffer, 1024 ) ) {
}
$class->updateStatus( $f->r, 'REDIRECT', $datas->{ $tsv->{whatToTrace} },
'filter' );
$class->updateStatus( $f->r, 'REDIRECT',
$datas->{ $tsv->{whatToTrace} }, 'filter' );
return OK;
}

View File

@ -234,4 +234,4 @@
$httpProvider.interceptors.push('$lmhttp');
}]);
})();
})();

View File

@ -92,7 +92,15 @@
};
}
else if (e == 401) {
if ($scope.portal) {
window.location = $scope.portal + window.btoa(window.location).replace(/\//, '_');
}
console.log('Authentication needed');
$scope.message = {
title: 'authenticationNeeded',
message: 'waitOrF5',
items: []
};
}
else if (e == 400) {
$scope.message = {

View File

@ -44,6 +44,7 @@
"authChoiceModules": "Allowed modules",
"authChoiceParam": "URL parameter",
"authentication": "Authentication module",
"authenticationNeeded": "Authentication needed",
"authenticationLevel": "Authentication level",
"authenticationTitle": "Authentication",
"AuthLDAPFilter": "Authentication filter",
@ -619,6 +620,7 @@
"webIDExportedVars": "Exported variables",
"webidParams": "WebID parameters",
"webIDWhitelist": "WebID whitelist",
"waitOrF5": "Wait for redirection or press F5",
"whatToTrace": "REMOTE_USER",
"whiteList": "White list",
"XMLcontent": "XML content",

View File

@ -44,6 +44,7 @@
"authChoiceModules": "Modules autorisés",
"authChoiceParam": "Paramètre de l'URL",
"authentication": "Module d'authentification",
"authenticationNeeded": "Authentification exigée",
"authenticationLevel": "Niveau d'authentification",
"authenticationTitle": "Authentification",
"AuthLDAPFilter": "Filtre d'authentification",
@ -619,6 +620,7 @@
"webIDExportedVars": "Variables exportées",
"webidParams": "Paramètres WebID",
"webIDWhitelist": "Liste blanche WebID",
"waitOrF5": "Attendez la redirection ou appuyez sur F5",
"whatToTrace": "REMOTE_USER",
"whiteList": "Liste blanche",
"XMLcontent": "Contenu XML",

View File

@ -1373,7 +1373,9 @@ sub printImage {
return;
}
print $self->header(
$type . '; charset=utf-8; content-length=' . ( stat($file) )[10] );
-type => "$type; charset=utf-8",
'-Content-Length' => ( stat($file) )[10]
);
my $buffer = "";
while ( read( IMAGE, $buffer, 4096 ) ) {
print $buffer;
@ -1505,6 +1507,23 @@ sub process {
issuerForAuthUser autoRedirect)
);
$self->updateStatus;
if ( !$self->{noAjaxHook}
and $self->http('Accept') =~ m#(?:application|text)/json# )
{
if ( ( my $code = $self->{error} ) > 0 ) {
print $self->header(
-status => '401 Unauthorizated',
'-WWW-Authenticate' => "SSO $self->{portal}",
'-Access-Control-Allow-Origin' => '*',
);
$self->quit;
}
else {
$self->header( -type => 'application/json' );
print '{"result":1,"message":"Authenticated"}';
$self->quit;
}
}
return ( ( $self->{error} > 0 ) ? 0 : 1 );
}
@ -1643,9 +1662,10 @@ sub controlExistingSession {
if ( $captcha && $captcha->image ) {
binmode STDOUT;
print $self->header( 'image/png'
. '; charset=utf-8; content-length='
. length( $captcha->image ) );
print $self->header(
-type => 'image/png; charset=utf-8',
'-Content-Length' => length( $captcha->image )
);
print $captcha->image;
}
$self->quit();