Commit 20764ad8 authored by Yadd's avatar Yadd
Browse files

New authentication and userDB backend : "Remote" can be used to check...

New authentication and userDB backend : "Remote" can be used to check authentication from a remote Lemonldap::NG portal using CDA

parent bed4b5ed
......@@ -41,7 +41,7 @@ sub TIEHASH {
data => { _session_id => $session_id },
modified => 0,
};
foreach (qw(proxy proxyOptions)) {
foreach (qw(proxy proxyOptions ns)) {
$self->{$_} = $args->{$_};
}
( $user, $password ) = ( $args->{User}, $args->{Password} );
......@@ -133,6 +133,11 @@ sub _connect {
sub _soapCall {
my $self = shift;
my $func = shift;
my $r = $self->_connect->$func(@_);
if ( $r->fault ) {
print STDERR "SOAP Error: " . $r->fault->{faultstring};
return ();
}
return $self->_connect->$func(@_)->result;
}
......
......@@ -81,11 +81,13 @@ example/slavePortal.pl
lib/Lemonldap/NG/Portal.pm
lib/Lemonldap/NG/Portal/_i18n.pm
lib/Lemonldap/NG/Portal/_LDAP.pm
lib/Lemonldap/NG/Portal/_Remote.pm
lib/Lemonldap/NG/Portal/_WebForm.pm
lib/Lemonldap/NG/Portal/AuthApache.pm
lib/Lemonldap/NG/Portal/AuthCAS.pm
lib/Lemonldap/NG/Portal/AuthLA.pm
lib/Lemonldap/NG/Portal/AuthLDAP.pm
lib/Lemonldap/NG/Portal/AuthRemote.pm
lib/Lemonldap/NG/Portal/AuthSSL.pm
lib/Lemonldap/NG/Portal/CDA.pm
lib/Lemonldap/NG/Portal/Error.pm
......@@ -96,6 +98,7 @@ lib/Lemonldap/NG/Portal/Notification/File.pm
lib/Lemonldap/NG/Portal/SharedConf.pm
lib/Lemonldap/NG/Portal/Simple.pm
lib/Lemonldap/NG/Portal/UserDBLDAP.pm
lib/Lemonldap/NG/Portal/UserDBRemote.pm
Makefile.PL
MANIFEST This list of files
META.yml
......
## @file
# Remote authentication module
## @class
# Remote authentication module: It simply check the remote session using cross
# domain mechanism.
package Lemonldap::NG::Portal::AuthRemote;
use strict;
use Lemonldap::NG::Portal::_Remote;
use Lemonldap::NG::Portal::Simple;
use base qw(Lemonldap::NG::Portal::_Remote);
*authInit = *Lemonldap::NG::Portal::_Remote::init;
## @apmethod int extractFormInfo()
# Call checkRemoteId() and set $self->{user} and $self->{password}
# @return Lemonldap::NG::Portal constant
sub extractFormInfo {
my $self = shift;
my $r = $self->checkRemoteId();
return $r unless ( $r == PE_OK );
$self->{user} =
$self->{rSessionInfo}->{ $self->{remoteUserField} || 'uid' };
$self->{password} = $self->{rSessionInfo}->{'_password'};
PE_OK;
}
## @apmethod int setAuthSessionInfo()
# Delete stored password if local policy does not accept stored passwords.
# @return Lemonldap::NG::Portal constant
sub setAuthSessionInfo {
PE_OK;
}
## @apmethod int authenticate()
# Does nothing.
# @return Lemonldap::NG::Portal constant
sub authenticate {
PE_OK;
}
1;
......@@ -317,11 +317,11 @@ sub redirect {
}
}
## @method protected hashref getRemoteSession(string id)
## @method protected hashref getApacheSession(string id)
# Try to recover the session corresponding to id and return session datas.
# If $id is set to undef, return a new session.
# @param $id session reference
sub getRemoteSession {
sub getApacheSession {
my ( $self, $id ) = @_;
my %h;
......@@ -340,6 +340,7 @@ sub getRemoteSession {
return 0;
}
$self->setApacheUser( $h{ $self->{whatToTrace} } ) if ($id);
$self->{id} = $h{_session_id};
return \%h;
}
......@@ -359,7 +360,7 @@ sub updateSession {
if ( $cookies{ $self->{cookieName} }
and my $id = $cookies{ $self->{cookieName} }->value )
{
my $h = $self->getRemoteSession($id) or return undef;
my $h = $self->getApacheSession($id) or return undef;
# Store/update session values
foreach ( keys %$infos ) {
......@@ -546,9 +547,6 @@ m#^https?://(?:$self->{reVHosts}|(?:[^/]*)?$self->{domain})(?::\d+)?(?:/.*)?$#
return PE_BADURL;
}
}
elsif ( $self->{mustRedirect} ) {
$self->{urldc} = $self->{portal};
}
PE_OK;
}
......@@ -587,8 +585,10 @@ sub controlExistingSession {
my %cookies;
%cookies = fetch CGI::Cookie unless ($id);
# Store IP address
# Store IP address and start time
$self->{sessionInfo}->{ipAddr} = $ENV{REMOTE_ADDR};
$self->{sessionInfo}->{startTime} =
&POSIX::strftime( "%Y%m%d%H%M%S", localtime() );
# Test if Lemonldap::NG cookie is available
if (
......@@ -597,7 +597,7 @@ sub controlExistingSession {
and $id = $cookies{ $self->{cookieName} }->value )
)
{
my $h = $self->getRemoteSession($id) or return PE_OK;
my $h = $self->getApacheSession($id) or return PE_OK;
%{ $self->{sessionInfo} } = %$h;
# Logout if required
......@@ -628,14 +628,7 @@ sub controlExistingSession {
$self->{id} = $id;
# A session has been find => calling &existingSession
my ($r);
if ( $self->{existingSession} ) {
$r =
&{ $self->{existingSession} }( $self, $id, $self->{sessionInfo} );
}
else {
$r = $self->existingSession( $id, $self->{sessionInfo} );
}
my $r = $self->_sub( 'existingSession', $id, $self->{sessionInfo} );
if ( $r == PE_DONE ) {
$self->{error} =
$self->_subProcess(qw(checkNotification autoRedirect));
......@@ -748,8 +741,7 @@ sub store {
# Now, user is authenticated => inform Apache
$self->setApacheUser( $self->{sessionInfo}->{ $self->{whatToTrace} } );
my $h = $self->getRemoteSession(undef) or return PE_APACHESESSIONERROR;
$self->{id} = $h->{_session_id};
my $h = $self->getApacheSession(undef) or return PE_APACHESESSIONERROR;
$h->{$_} = $self->{sessionInfo}->{$_}
foreach ( keys %{ $self->{sessionInfo} } );
$h->{_utime} = time();
......@@ -796,6 +788,9 @@ sub checkNotification {
sub autoRedirect {
my $self = shift;
# default redirection URL
$self->{urldc} ||= $self->{portal} if ( $self->{mustRedirect} );
# Redirection should be made if
# - urldc defined
# - no warnings on ppolicy
......@@ -804,16 +799,16 @@ sub autoRedirect {
and !$self->{ppolicy}->{grace_authentications_remaining} )
{
# Cross-domain mechanism
# Cross-domain mechanism
if ( $self->{CDA}
and $self->{id}
and $self->{urldc} !~ m#^https?://[^/]*$self->{domain}/#oi )
{
$self->lmLog( 'CDA request', 'debug' );
$self->{urldc} .=
( $self->{urldc} =~ /\?/oi )
? '&'
: '?' . $self->{cookieName} . "=" . $self->{id};
( $self->{urldc} =~ /\?/ ? '&' : '?' )
. $self->{cookieName} . "="
. $self->{id};
}
$self->updateStatus;
print $self->SUPER::redirect(
......
......@@ -71,8 +71,6 @@ sub search {
sub setSessionInfo {
my ($self) = @_;
$self->{sessionInfo}->{dn} = $self->{dn};
$self->{sessionInfo}->{startTime} =
&POSIX::strftime( "%Y%m%d%H%M%S", localtime() );
unless ( $self->{exportedVars} ) {
foreach (qw(uid cn mail)) {
$self->{sessionInfo}->{$_} =
......
## @file
# Remote userDB mechanism
## @class
# Remote userDB mechanism class
package Lemonldap::NG::Portal::UserDBRemote;
use strict;
use Lemonldap::NG::Portal::_Remote;
use Lemonldap::NG::Portal::Simple;
use base qw(Lemonldap::NG::Portal::_Remote);
## @apmethod int userDBInit()
# Call Lemonldap::NG::Portal::_Remote::init();
# @return Lemonldap::NG::Portal constant
*userDBInit = *Lemonldap::NG::Portal::_Remote::init;
## @apmethod int getUser()
# Call checkRemoteId();
# @return Lemonldap::NG::Portal constant
*getUser = *Lemonldap::NG::Portal::_Remote::checkRemoteId;
## @apmethod int
# @return Lemonldap::NG::Portal constant
sub setSessionInfo {
my $self = shift;
delete $self->{rSessionInfo}->{_session_id};
$self->{sessionInfo} = $self->{rSessionInfo};
PE_OK;
}
1;
## @file
# Remote authentication and userDB base.
## @class
# Remote authentication and userDB base class.
package Lemonldap::NG::Portal::_Remote;
use strict;
use Lemonldap::NG::Portal::Simple;
use MIME::Base64;
## @apmethod int init()
# Checks if remote portal parameters are set.
# @return Lemonldap::NG::Portal constant
sub init {
my $self = shift;
my @missing = ();
foreach (qw(remotePortal remoteGlobalStorage)) {
push @missing, $_ unless ( defined( $self->{$_} ) );
}
$self->abort( "Missing parameters",
"Required parameters: " . join( ', ', @missing ) )
if (@missing);
eval "require " . $self->{remoteGlobalStorage};
$self->abort( "Configuration error",
"Module " . $self->{remoteGlobalStorage} . " not found in \@INC" )
if ($@);
$self->{remoteCookieName} ||= $self->{cookieName};
PE_OK;
}
## @apmethod int checkRemoteId()
# check if a CDA mechanism has been instanciated and if session is available.
# Redirect the user to the remote portal else by calling goToPortal().
# @return Lemonldap::NG::Portal constant
sub checkRemoteId {
my $self = shift;
my %h;
if ( my $rId = $self->param( $self->{remoteCookieName} ) ) {
$self->{mustRedirect} = 1;
# Trying to recover session from global session storage
# Note that since user has just been redirect to the remote portal, $@
# can not be "Object does not exist in the data store"
eval {
tie %h, $self->{remoteGlobalStorage}, $rId,
$self->{remoteGlobalStorageOptions};
};
if ( $@ or not tied(%h) ) {
$self->lmLog( "Remote session error: $@", 'error' );
return PE_ERROR;
}
%{ $self->{rSessionInfo} } = %h;
untie %h;
delete( $self->{rSessionInfo}->{'_password'} )
unless ( $self->{storePassword} );
return PE_OK;
}
return $self->_sub('goToPortal');
}
## @method protected void goToPortal()
# Redirect the user to the remote portal.
sub goToPortal {
my $self = shift;
print $self->redirect(
$self->{remotePortal} . "?url="
. encode_base64(
$self->{portal}
. ( $ENV{QUERY_STRING} ? "?$ENV{QUERY_STRING}" : '' ),
''
)
);
exit;
}
1;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment