LEMONLDAP::NG : * new auth architecture
* environment variables can now be used in exportedVars (usefull to access to SSL variables) * UTF-8 in examples * Romanian translation of portal
This commit is contained in:
parent
9b523a3534
commit
7bac798370
|
@ -2,6 +2,10 @@ Revision history for Perl extension Lemonldap::NG::Portal.
|
|||
|
||||
0.83 Sat May 24 17:24:23 2008
|
||||
- Integration in Handler status system
|
||||
- Romanian translation
|
||||
- New auth architecture
|
||||
- ENV variables are now available using exportedValue (can be used to
|
||||
send SSL variables to the remote application)
|
||||
|
||||
0.82 Mon Apr 7 15:01:02 2008
|
||||
- 2 Net::LDAP password policy controls in the portal:
|
||||
|
|
|
@ -50,6 +50,7 @@ lib/Lemonldap/NG/Portal/_i18n.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/AuthSSL.pm
|
||||
lib/Lemonldap/NG/Portal/CDA.pm
|
||||
lib/Lemonldap/NG/Portal/SharedConf.pm
|
||||
|
@ -58,12 +59,12 @@ Makefile.PL
|
|||
MANIFEST This list of files
|
||||
META.yml
|
||||
README
|
||||
t/01-Lemonldap-NG-Portal-Simple.t
|
||||
t/02-Lemonldap-NG-Portal-SharedConf.t
|
||||
t/10-Lemonldap-NG-Portal-i18n.t
|
||||
t/20-Lemonldap-NG-Portal-AuthApache.t
|
||||
t/21-Lemonldap-NG-Portal-AuthSSL.t
|
||||
t/22-Lemonldap-NG-Portal-AuthCAS.t
|
||||
t/23-Lemonldap-NG-Portal-AuthLA.t
|
||||
t/40-Lemonldap-NG-Portal-CDA.t
|
||||
t/99-pod.t
|
||||
t/Lemonldap-NG-Portal-AuthApache.t
|
||||
t/Lemonldap-NG-Portal-AuthCAS.t
|
||||
t/Lemonldap-NG-Portal-AuthLA.t
|
||||
t/Lemonldap-NG-Portal-AuthSSL.t
|
||||
t/Lemonldap-NG-Portal-CDA.t
|
||||
t/Lemonldap-NG-Portal-i18n.t
|
||||
t/Lemonldap-NG-Portal-SharedConf.t
|
||||
t/Lemonldap-NG-Portal-Simple.t
|
||||
|
|
|
@ -40,7 +40,7 @@ my $portal = Lemonldap::NG::Portal::AuthLA->new({
|
|||
|
||||
if( $portal->process() ) {
|
||||
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
my $template = HTML::Template->new( filename => "__DIR__/tpl/menu.tpl");
|
||||
|
||||
my @sites = ();
|
||||
|
|
|
@ -12,14 +12,14 @@ my $portal = Lemonldap::NG::Portal::SharedConf->new(
|
|||
);
|
||||
|
||||
if ( $portal->process() ) {
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
print $portal->start_html;
|
||||
print "<h1>Your well authenticated !</h1>";
|
||||
print "Click <a href=\"$ENV{SCRIPT_NAME}?logout=1\">here</a> to logout";
|
||||
print $portal->end_html;
|
||||
}
|
||||
else {
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
print $portal->start_html;
|
||||
print 'Error: ' . $portal->error . '<br />';
|
||||
print '<form method="post" action="'.$ENV{SCRIPTNAME}.'">';
|
||||
|
|
|
@ -22,7 +22,7 @@ $template->param(AUTH_TITLE => "LemonLDAP::NG Portal");
|
|||
$template->param(CSS_FILE => "skins/$skin/default.css");
|
||||
|
||||
if ( $portal->process() ) {
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
|
||||
# Get sites
|
||||
my @sites = ();
|
||||
|
@ -40,7 +40,7 @@ if ( $portal->process() ) {
|
|||
|
||||
print $template->output;
|
||||
} else {
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
$template->param(AUTH_ERROR => $portal->error);
|
||||
$template->param(AUTH_URL => $portal->param('url'));
|
||||
print $template->output;
|
||||
|
|
|
@ -105,13 +105,13 @@ my $portal = Lemonldap::NG::Portal::CDA->new(
|
|||
# Else, we process as usual, but without prompting users with a form
|
||||
|
||||
if ( $portal->process() ) {
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
print $portal->start_html;
|
||||
print "<h1>Your well authenticated !</h1>";
|
||||
print $portal->end_html;
|
||||
}
|
||||
else {
|
||||
print $portal->header;
|
||||
print $portal->header('text/html; charset=utf8');
|
||||
print $portal->start_html;
|
||||
print qq#<h2>Authentication failed</h2>
|
||||
Portal is not able to recognize you
|
||||
|
|
|
@ -32,7 +32,7 @@ system.
|
|||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here by a Lemonldap::NG::Handler,
|
||||
# else, the process sub redirect the user to the initial requested URI.
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -45,7 +45,7 @@ system.
|
|||
# Write here the html form used to authenticate with CGI methods.
|
||||
# $portal->error returns the error message if authentification failed
|
||||
# Warning: by defaut, input names are "user" and "password"
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "<html> ...";
|
||||
print '<form method="POST">';
|
||||
# In your form, the following value is required for redirection
|
||||
|
|
|
@ -3,25 +3,30 @@ package Lemonldap::NG::Portal::AuthApache;
|
|||
use strict;
|
||||
use Lemonldap::NG::Portal::Simple;
|
||||
|
||||
our $VERSION = '0.01';
|
||||
our $VERSION = '0.1';
|
||||
|
||||
our $OVERRIDE = {
|
||||
# By default, authentication is valid if REMOTE_USER environment
|
||||
# variable is present. Change formateFilter if this does not match with
|
||||
# UID.
|
||||
extractFormInfo => sub {
|
||||
my $self = shift;
|
||||
return PE_FORMEMPTY unless( $self->{user} = $ENV{REMOTE_USER} );
|
||||
# This is needed for Kerberos authentication
|
||||
$self->{user} =~ s/(.*)@(.*)/$1/g;
|
||||
PE_OK;
|
||||
},
|
||||
sub authInit {
|
||||
}
|
||||
|
||||
# Authentication is made by Apache.
|
||||
authenticate => sub {
|
||||
PE_OK;
|
||||
},
|
||||
};
|
||||
# By default, authentication is valid if REMOTE_USER environment
|
||||
# variable is present. Change formateFilter if this does not match with
|
||||
# UID.
|
||||
sub extractFormInfo {
|
||||
my $self = shift;
|
||||
unless ( $self->{user} = $ENV{REMOTE_USER} ) {
|
||||
print STDERR "Apache is not configured to authenticate users !";
|
||||
return PE_ERROR;
|
||||
}
|
||||
|
||||
# This is needed for Kerberos authentication
|
||||
$self->{user} =~ s/^(.*)@.*$/$1/g;
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
# Authentication is made by Apache.
|
||||
sub authenticate {
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
@ -42,7 +47,7 @@ compatible portals with Apache authentication.
|
|||
if($portal->process()) {
|
||||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here.
|
||||
print $portal->header; # DON'T FORGET THIS (see CGI(3))
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -50,7 +55,7 @@ compatible portals with Apache authentication.
|
|||
}
|
||||
else {
|
||||
# If the user enters here, IT MEANS THAT CAS REDIRECTION DOES NOT WORK
|
||||
print $portal->header; # DON'T FORGET THIS (see CGI(3))
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
|
||||
print "<html><body><h1>Unable to work</h1>";
|
||||
print "This server isn't well configured. Contact your administrator.";
|
||||
print "</body></html>";
|
||||
|
|
|
@ -4,32 +4,37 @@ use strict;
|
|||
use Lemonldap::NG::Portal::Simple;
|
||||
use AuthCAS;
|
||||
|
||||
our $VERSION = '0.02';
|
||||
our $VERSION = '0.03';
|
||||
|
||||
our $OVERRIDE = {
|
||||
extractFormInfo => sub {
|
||||
my $self = shift;
|
||||
my $cas = new AuthCAS(casUrl => $self->{CAS_url},
|
||||
CAFile => $self->{CAS_CAFile},
|
||||
);
|
||||
my $login_url = $cas->getServerLoginURL($self->{CAS_loginUrl});
|
||||
sub authInit {
|
||||
}
|
||||
|
||||
my $ticket = $self->param('ticket');
|
||||
# Unless a ticket has been found, we redirect the user
|
||||
unless( $self->{user} = $cas->validateST($self->{CAS_validationUrl}, $ticket) ) {
|
||||
print $self->SUPER::redirect(
|
||||
-uri => $login_url,
|
||||
-status => '302 Moved Temporary'
|
||||
);
|
||||
exit;
|
||||
}
|
||||
PE_OK;
|
||||
},
|
||||
sub extractFormInfo {
|
||||
my $self = shift;
|
||||
my $cas = new AuthCAS(
|
||||
casUrl => $self->{CAS_url},
|
||||
CAFile => $self->{CAS_CAFile},
|
||||
);
|
||||
my $login_url = $cas->getServerLoginURL( $self->{CAS_loginUrl} );
|
||||
|
||||
authenticate => sub {
|
||||
PE_OK;
|
||||
},
|
||||
};
|
||||
my $ticket = $self->param('ticket');
|
||||
|
||||
# Unless a ticket has been found, we redirect the user
|
||||
unless ( $self->{user} =
|
||||
$cas->validateST( $self->{CAS_validationUrl}, $ticket ) )
|
||||
{
|
||||
print $self->SUPER::redirect(
|
||||
-uri => $login_url,
|
||||
-status => '302 Moved Temporary'
|
||||
);
|
||||
exit;
|
||||
}
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
sub authenticate {
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
@ -54,7 +59,7 @@ compatible portals with CAS authentication. EXPERIMENTAL AND NOT FINISHED!
|
|||
if($portal->process()) {
|
||||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here.
|
||||
print $portal->header; # DON'T FORGET THIS (see CGI(3))
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -62,7 +67,7 @@ compatible portals with CAS authentication. EXPERIMENTAL AND NOT FINISHED!
|
|||
}
|
||||
else {
|
||||
# If the user enters here, IT MEANS THAT CAS REDIRECTION DOES NOT WORK
|
||||
print $portal->header; # DON'T FORGET THIS (see CGI(3))
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
|
||||
print "<html><body><h1>Unable to work</h1>";
|
||||
print "This server isn't well configured. Contact your administrator.";
|
||||
print "</body></html>";
|
||||
|
|
|
@ -2,77 +2,50 @@ package Lemonldap::NG::Portal::AuthSSL;
|
|||
|
||||
use strict;
|
||||
use Lemonldap::NG::Portal::Simple;
|
||||
use Lemonldap::NG::Portal::AuthLDAP;
|
||||
|
||||
our @ISA = qw(Lemonldap::NG::Portal::AuthLDAP);
|
||||
|
||||
our $VERSION = '0.1';
|
||||
|
||||
sub authInit {
|
||||
my $self = shift;
|
||||
$self->{SSLRequire} = 1 unless ( defined $self->{SSLRequire} );
|
||||
$self->{SSLVar} ||= 'SSL_CLIENT_S_DN_Email';
|
||||
$self->{SSLLDAPField} ||= 'mail';
|
||||
}
|
||||
|
||||
# Authentication is made by Apache with SSL and here before searching the LDAP
|
||||
# Directory.
|
||||
# So authenticate is overloaded to return only PE_OK.
|
||||
|
||||
our $OVERRIDE = {
|
||||
sub extractFormInfo {
|
||||
my $self = shift;
|
||||
my $user = $self->https ? $ENV{ $self->{SSLVar} } : 0;
|
||||
if ($user) {
|
||||
$self->{sessionInfo}->{authenticationLevel} = 5;
|
||||
$self->{user} = $user;
|
||||
$self->{authFilter} =
|
||||
'(&(' . $self->{SSLLDAPField} . "=$user)(objectClass=inetOrgPerson))";
|
||||
return PE_OK;
|
||||
}
|
||||
elsif ( $self->{SSLRequire} ) {
|
||||
return PE_CERTIFICATEREQUIRED;
|
||||
}
|
||||
$self->{authFilter} = '';
|
||||
return $self->SUPER::extractFormInfo(@_);
|
||||
}
|
||||
|
||||
# By default, authentication is valid if SSL_CLIENT_S_DN_Email environment
|
||||
# variable is present. Adapt it if you want
|
||||
extractFormInfo => sub {
|
||||
my $self = shift;
|
||||
|
||||
# Defaults values
|
||||
$self->{SSLRequire} = 1 unless ( defined $self->{SSLRequire} );
|
||||
$self->{SSLVar} ||= 'SSL_CLIENT_S_DN_Email';
|
||||
$self->{SSLLDAPField} ||= 'mail';
|
||||
|
||||
my $user = $self->https ? $ENV{$self->{SSLVar}} : 0;
|
||||
if ($user) {
|
||||
$self->{sessionInfo}->{authenticationLevel} = 5;
|
||||
$self->{user} = $user;
|
||||
return PE_OK;
|
||||
}
|
||||
elsif ( $self->{SSLRequire} ) {
|
||||
return PE_CERTIFICATEREQUIRED;
|
||||
}
|
||||
return $self->extractFormInfo(@_);
|
||||
},
|
||||
|
||||
# As we know only user mail (or SSLVar), we have to use it to find him in
|
||||
# the LDAP directory
|
||||
formateFilter => sub {
|
||||
my $self = shift;
|
||||
if ( $self->{sessionInfo}->{authenticationLevel} and $self->{sessionInfo}->{authenticationLevel} > 4 ) {
|
||||
$self->{filter} = '(&('
|
||||
. $self->{SSLLDAPField} . '='
|
||||
. $self->{user}
|
||||
. ")(objectClass=person))";
|
||||
return PE_OK;
|
||||
}
|
||||
return $self->formateFilter(@_);
|
||||
},
|
||||
|
||||
# Apache SSL environment variable are available in exportedVars:
|
||||
setSessionInfo => sub {
|
||||
my $self = shift;
|
||||
my $save = $self->{exportedVars};
|
||||
if ( ref( $self->{exportedVars} ) eq 'HASH' ) {
|
||||
foreach ( keys %{ $self->{exportedVars} } ) {
|
||||
if (/^SSL/) {
|
||||
$self->{sessionInfo}->{$_} = $ENV{$_};
|
||||
delete $self->{exportedVars}->{$_};
|
||||
}
|
||||
}
|
||||
}
|
||||
my $r = $self->setSessionInfo(@_);
|
||||
$self->{exportedVars} = $save;
|
||||
return $r;
|
||||
},
|
||||
|
||||
# If authentication has been done with SSL, LDAP bind is disabled
|
||||
authenticate => sub {
|
||||
my $self = shift;
|
||||
if ( $self->{sessionInfo}->{authenticationLevel} and $self->{sessionInfo}->{authenticationLevel} > 4 ) {
|
||||
return PE_OK;
|
||||
}
|
||||
return $self->authenticate(@_);
|
||||
},
|
||||
};
|
||||
# If authentication has been done with SSL, LDAP bind is disabled
|
||||
sub authenticate {
|
||||
my $self = shift;
|
||||
if ( $self->{sessionInfo}->{authenticationLevel}
|
||||
and $self->{sessionInfo}->{authenticationLevel} > 4 )
|
||||
{
|
||||
return PE_OK;
|
||||
}
|
||||
return $self->SUPER::authenticate(@_);
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
@ -119,7 +92,7 @@ With Lemonldap::NG::Portal::Simple:
|
|||
if($portal->process()) {
|
||||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here.
|
||||
print $portal->header; # DON'T FORGET THIS (see CGI(3))
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -127,7 +100,7 @@ With Lemonldap::NG::Portal::Simple:
|
|||
}
|
||||
else {
|
||||
# If the user enters here, IT MEANS THAT YOUR SSL PARAMETERS ARE BAD
|
||||
print $portal->header; # DON'T FORGET THIS (see CGI(3))
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
|
||||
print "<html><body><h1>Unable to work</h1>";
|
||||
print "This server isn't well configured. Contact your administrator.";
|
||||
print "</body></html>";
|
||||
|
|
|
@ -56,7 +56,7 @@ compatible portals with Cross Domain Authentication.
|
|||
if($portal->process()) {
|
||||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here.
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -66,7 +66,7 @@ compatible portals with Cross Domain Authentication.
|
|||
# Write here the html form used to authenticate with CGI methods.
|
||||
# $portal->error returns the error message if athentification failed
|
||||
# Warning: by defaut, input names are "user" and "password"
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
print '<form method="POST">';
|
||||
# In your form, the following value is required for redirection
|
||||
|
|
|
@ -234,7 +234,7 @@ compatible portals using a central configuration database.
|
|||
if($portal->process()) {
|
||||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here.
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -244,7 +244,7 @@ compatible portals using a central configuration database.
|
|||
# Write here the html form used to authenticate with CGI methods.
|
||||
# $portal->error returns the error message if athentification failed
|
||||
# Warning: by defaut, input names are "user" and "password"
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
print '<form method="POST">';
|
||||
# In your form, the following value is required for redirection
|
||||
|
|
|
@ -19,23 +19,23 @@ our @ISA = qw(CGI Exporter);
|
|||
|
||||
# Constants
|
||||
use constant {
|
||||
PE_REDIRECT => -2,
|
||||
PE_DONE => -1,
|
||||
PE_OK => 0,
|
||||
PE_SESSIONEXPIRED => 1,
|
||||
PE_FORMEMPTY => 2,
|
||||
PE_WRONGMANAGERACCOUNT => 3,
|
||||
PE_USERNOTFOUND => 4,
|
||||
PE_BADCREDENTIALS => 5,
|
||||
PE_LDAPCONNECTFAILED => 6,
|
||||
PE_LDAPERROR => 7,
|
||||
PE_APACHESESSIONERROR => 8,
|
||||
PE_FIRSTACCESS => 9,
|
||||
PE_BADCERTIFICATE => 10,
|
||||
PE_PP_ACCOUNT_LOCKED => 21,
|
||||
PE_PP_PASSWORD_EXPIRED => 22,
|
||||
PE_CERTIFICATEREQUIRED => 23,
|
||||
PE_ERROR => 24,
|
||||
PE_REDIRECT => -2,
|
||||
PE_DONE => -1,
|
||||
PE_OK => 0,
|
||||
PE_SESSIONEXPIRED => 1,
|
||||
PE_FORMEMPTY => 2,
|
||||
PE_WRONGMANAGERACCOUNT => 3,
|
||||
PE_USERNOTFOUND => 4,
|
||||
PE_BADCREDENTIALS => 5,
|
||||
PE_LDAPCONNECTFAILED => 6,
|
||||
PE_LDAPERROR => 7,
|
||||
PE_APACHESESSIONERROR => 8,
|
||||
PE_FIRSTACCESS => 9,
|
||||
PE_BADCERTIFICATE => 10,
|
||||
PE_PP_ACCOUNT_LOCKED => 21,
|
||||
PE_PP_PASSWORD_EXPIRED => 22,
|
||||
PE_CERTIFICATEREQUIRED => 23,
|
||||
PE_ERROR => 24,
|
||||
};
|
||||
|
||||
# EXPORTER PARAMETERS
|
||||
|
@ -43,7 +43,8 @@ our @EXPORT =
|
|||
qw( PE_DONE PE_OK PE_SESSIONEXPIRED PE_FORMEMPTY PE_WRONGMANAGERACCOUNT
|
||||
PE_USERNOTFOUND PE_BADCREDENTIALS PE_LDAPCONNECTFAILED PE_LDAPERROR
|
||||
PE_APACHESESSIONERROR PE_FIRSTACCESS PE_BADCERTIFICATE PE_REDIRECT
|
||||
PE_PP_ACCOUNT_LOCKED PE_PP_PASSWORD_EXPIRED PE_CERTIFICATEREQUIRED);
|
||||
PE_PP_ACCOUNT_LOCKED PE_PP_PASSWORD_EXPIRED PE_CERTIFICATEREQUIRED
|
||||
PE_ERROR);
|
||||
our %EXPORT_TAGS = ( 'all' => [ @EXPORT, 'import' ], );
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
|
@ -64,21 +65,24 @@ sub new {
|
|||
$self->{securedCookie} ||= 0;
|
||||
$self->{cookieName} ||= "lemonldap";
|
||||
$self->{ldapPpolicyControl} ||= 0;
|
||||
$self->{authentication} ||= 'LDAP';
|
||||
$self->{authentication} =~ s/^ldap/LDAP/;
|
||||
|
||||
if ( $self->{authentication} and $self->{authentication} ne "ldap" ) {
|
||||
# Authentication module is required and has to be in @ISA
|
||||
my $tmp = 'Lemonldap::NG::Portal::Auth' . $self->{authentication};
|
||||
$tmp =~ s/\s.*$//;
|
||||
eval "require $tmp";
|
||||
die($@) if ($@);
|
||||
push @ISA, $tmp;
|
||||
|
||||
# $Lemonldap::NG::Portal::AuthSSL::OVERRIDE does not overload $self
|
||||
# variables: if the administrator has defined a sub, we respect it
|
||||
my $tmp =
|
||||
'require Lemonldap::NG::Portal::Auth'
|
||||
. $self->{authentication}
|
||||
. '; $tmp = $Lemonldap::NG::Portal::Auth'
|
||||
. $self->{authentication}
|
||||
. '::OVERRIDE;';
|
||||
eval $tmp;
|
||||
die($@) if ($@);
|
||||
%$self = ( %$tmp, %$self );
|
||||
}
|
||||
# $self->{authentication} can contains arguments (key1 = scalar_value;
|
||||
# key2 = ...)
|
||||
$tmp = $self->{authentication};
|
||||
$tmp =~ s/^\w+\s*//;
|
||||
my %h = split( /\s*[=;]\s*/, $tmp) if($tmp);
|
||||
%$self = ( %h, %$self );
|
||||
|
||||
$self->authInit();
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
@ -100,13 +104,13 @@ sub getConf {
|
|||
sub error {
|
||||
my $self = shift;
|
||||
return &Lemonldap::NG::Portal::_i18n::error( $self->{error},
|
||||
$ENV{HTTP_ACCEPT_LANGUAGE} );
|
||||
shift || $ENV{HTTP_ACCEPT_LANGUAGE} );
|
||||
}
|
||||
|
||||
# Private sub used to bind to LDAP server both with Lemonldap::NG account and user
|
||||
# credentials if LDAP authentication is used
|
||||
sub _bind {
|
||||
my ( $ldap, $dn, $password ) = @_;
|
||||
my ( $self, $ldap, $dn, $password ) = @_;
|
||||
my $mesg;
|
||||
if ( $dn and $password ) { # named bind
|
||||
$mesg = $ldap->bind( $dn, password => $password );
|
||||
|
@ -174,13 +178,17 @@ sub updateStatus {
|
|||
# different than PE_OK #
|
||||
###############################################################
|
||||
|
||||
# extractFormInfo, setAuthSessionInfo and authenticate must be implemented in
|
||||
# auth modules
|
||||
|
||||
sub process {
|
||||
my ($self) = @_;
|
||||
$self->{error} = PE_OK;
|
||||
$self->{error} = $self->_subProcess(
|
||||
qw(controlUrlOrigin controlExistingSession extractFormInfo formateParams
|
||||
formateFilter connectLDAP bind search setSessionInfo setMacros setGroups
|
||||
authenticate store unbind buildCookie log autoRedirect)
|
||||
formateFilter connectLDAP bind search setAuthSessionInfo
|
||||
setSessionInfo setMacros setGroups authenticate store unbind
|
||||
buildCookie log autoRedirect)
|
||||
);
|
||||
$self->updateStatus;
|
||||
return ( ( $self->{error} > 0 ) ? 0 : 1 );
|
||||
|
@ -256,7 +264,7 @@ sub controlExistingSession {
|
|||
$r = $self->existingSession( $id, $datas );
|
||||
}
|
||||
if ( $r == PE_DONE ) {
|
||||
$self->{error} = _subProcess(qw(log autoRedirect));
|
||||
$self->{error} = $self->_subProcess(qw(log autoRedirect));
|
||||
return $self->{error} || PE_DONE;
|
||||
}
|
||||
else {
|
||||
|
@ -271,18 +279,6 @@ sub existingSession {
|
|||
PE_OK;
|
||||
}
|
||||
|
||||
# 3. In ldap authentication scheme, we load here user and password from HTML
|
||||
# form
|
||||
sub extractFormInfo {
|
||||
my $self = shift;
|
||||
return PE_FIRSTACCESS
|
||||
unless ( $self->param('user') );
|
||||
return PE_FORMEMPTY
|
||||
unless ( length( $self->{'user'} = $self->param('user') ) > 0
|
||||
&& length( $self->{'password'} = $self->param('password') ) > 0 );
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
# Unused. You can overload if you have to modify user and password before
|
||||
# authentication
|
||||
sub formateParams() {
|
||||
|
@ -293,7 +289,8 @@ sub formateParams() {
|
|||
# it with Active Directory, overload it to use CN instead of UID.
|
||||
sub formateFilter {
|
||||
my $self = shift;
|
||||
$self->{filter} = "(&(uid=" . $self->{user} . ")(objectClass=inetOrgPerson))";
|
||||
$self->{filter} = $self->{authFilter} ||
|
||||
"(&(uid=" . $self->{user} . ")(objectClass=inetOrgPerson))";
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
|
@ -336,7 +333,10 @@ sub bind {
|
|||
$self->connectLDAP unless ( $self->{ldap} );
|
||||
return PE_WRONGMANAGERACCOUNT
|
||||
unless (
|
||||
&_bind( $self->{ldap}, $self->{managerDn}, $self->{managerPassword} ) );
|
||||
$self->_bind(
|
||||
$self->{ldap}, $self->{managerDn}, $self->{managerPassword}
|
||||
)
|
||||
);
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
|
@ -357,6 +357,8 @@ sub search {
|
|||
PE_OK;
|
||||
}
|
||||
|
||||
# sub setAuthSessionInfo has to be defined in auth module
|
||||
|
||||
# 8. Load all parameters included in exportedVars parameter.
|
||||
# Multi-value parameters are loaded in a single string with
|
||||
# '; ' separator
|
||||
|
@ -373,16 +375,19 @@ sub setSessionInfo {
|
|||
}
|
||||
elsif ( ref( $self->{exportedVars} ) eq 'HASH' ) {
|
||||
foreach ( keys %{ $self->{exportedVars} } ) {
|
||||
$self->{sessionInfo}->{$_} = join( '; ',
|
||||
$self->{entry}->get_value( $self->{exportedVars}->{$_} ) )
|
||||
|| "";
|
||||
if ( my $tmp = $ENV{$_} ) {
|
||||
$tmp =~ s/[\r\n]/ /gs;
|
||||
$self->{sessionInfo}->{$_} = $tmp;
|
||||
}
|
||||
else {
|
||||
$self->{sessionInfo}->{$_} = join( '; ',
|
||||
$self->{entry}->get_value( $self->{exportedVars}->{$_} ) )
|
||||
|| "";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ( @{ $self->{exportedVars} } ) {
|
||||
$self->{sessionInfo}->{$_} =
|
||||
join( '; ', $self->{entry}->get_value($_) ) || "";
|
||||
}
|
||||
die('Only hash reference are supported now in exportedVars');
|
||||
}
|
||||
PE_OK;
|
||||
}
|
||||
|
@ -406,64 +411,6 @@ sub unbind {
|
|||
PE_OK;
|
||||
}
|
||||
|
||||
# 12. Default authentication: LDAP bind with user credentials
|
||||
sub authenticate {
|
||||
my $self = shift;
|
||||
$self->unbind();
|
||||
my $err;
|
||||
return $err unless ( ( $err = $self->connectLDAP ) == PE_OK );
|
||||
|
||||
# Check if we use Ppolicy control
|
||||
if ( $self->{ldapPpolicyControl} ) {
|
||||
|
||||
# require Perl module
|
||||
eval 'require Net::LDAP::Control::PasswordPolicy';
|
||||
die('Module Net::LDAP::Control::PasswordPolicy not found in @INC')
|
||||
if ($@);
|
||||
eval
|
||||
'use Net::LDAP::Constant qw( LDAP_CONTROL_PASSWORDPOLICY LDAP_PP_ACCOUNT_LOCKED LDAP_PP_PASSWORD_EXPIRED );';
|
||||
no strict 'subs';
|
||||
|
||||
# Create Control object
|
||||
my $pp = Net::LDAP::Control::PasswordPolicy->new;
|
||||
|
||||
# Bind with user credentials
|
||||
my $mesg = $self->{ldap}->bind(
|
||||
$self->{dn},
|
||||
password => $self->{password},
|
||||
control => [$pp]
|
||||
);
|
||||
|
||||
# Get bind response
|
||||
return PE_OK if ( $mesg->code == 0 );
|
||||
|
||||
# Get server control response
|
||||
my ($resp) = $mesg->control(LDAP_CONTROL_PASSWORDPOLICY);
|
||||
|
||||
if ( defined $resp ) {
|
||||
my $pp_error = $resp->error;
|
||||
if ($pp_error) {
|
||||
return PE_PP_ACCOUNT_LOCKED
|
||||
if ( $pp_error == LDAP_PP_ACCOUNT_LOCKED );
|
||||
return PE_PP_PASSWORD_EXPIRED
|
||||
if ( $pp_error == LDAP_PP_PASSWORD_EXPIRED );
|
||||
}
|
||||
else {
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return PE_LDAPERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return PE_BADCREDENTIALS
|
||||
unless ( &_bind( $self->{ldap}, $self->{dn}, $self->{password} ) );
|
||||
}
|
||||
$self->{sessionInfo}->{authenticationLevel} = 2;
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
# 13. Now, the user is authenticated. It's time to store his parameters with
|
||||
# Apache::Session::* module
|
||||
sub store {
|
||||
|
@ -487,7 +434,7 @@ sub store {
|
|||
# 14. If all is done, we build the Lemonldap::NG cookie
|
||||
sub buildCookie {
|
||||
my $self = shift;
|
||||
$self->{cookie} = $self->cookie(
|
||||
push @{$self->{cookie}}, $self->cookie(
|
||||
-name => $self->{cookieName},
|
||||
-value => $self->{id},
|
||||
-domain => $self->{domain},
|
||||
|
@ -575,7 +522,7 @@ Lemonldap::NG::Portal::Simple - Base module for building Lemonldap::NG compatibl
|
|||
if($portal->process()) {
|
||||
# Write here the menu with CGI methods. This page is displayed ONLY IF
|
||||
# the user was not redirected here.
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
|
||||
# or redirect the user to the menu
|
||||
|
@ -585,7 +532,7 @@ Lemonldap::NG::Portal::Simple - Base module for building Lemonldap::NG compatibl
|
|||
# Write here the html form used to authenticate with CGI methods.
|
||||
# $portal->error returns the error message if athentification failed
|
||||
# Warning: by defaut, input names are "user" and "password"
|
||||
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
|
||||
print "...";
|
||||
print '<form method="POST">';
|
||||
# In your form, the following value is required for redirection
|
||||
|
@ -764,7 +711,7 @@ described above
|
|||
|
||||
=head3 _bind( $ldap, $dn, $password )
|
||||
|
||||
Non-object method used to bind to the ldap server.
|
||||
Method used to bind to the ldap server.
|
||||
|
||||
=head3 header
|
||||
|
||||
|
|
|
@ -1,26 +1,31 @@
|
|||
package Lemonldap::NG::Portal::_i18n;
|
||||
|
||||
# Developpers warning : this file must stay UTF-8 encoded
|
||||
|
||||
use AutoLoader qw(AUTOLOAD);
|
||||
our $VERSION = '0.11';
|
||||
our $VERSION = '0.2';
|
||||
|
||||
sub error {
|
||||
my($error,$lang) = @_;
|
||||
my ( $error, $lang ) = @_;
|
||||
$lang = lc($lang);
|
||||
$lang =~ s/-/_/g;
|
||||
$error = 0 if ( $error < 0 );
|
||||
foreach ( split( /[,;]/, $lang ) ) {
|
||||
next if /=/;
|
||||
if ( __PACKAGE__->can("error_$_") ) {
|
||||
return &{"error_$_"}->[$error];
|
||||
}
|
||||
s/^(..).*$/$1/;
|
||||
if ( __PACKAGE__->can("error_$_") ) {
|
||||
return &{"error_$_"}->[$error];
|
||||
}
|
||||
}
|
||||
return &error_en->[$error];
|
||||
}
|
||||
|
||||
*error_fr_fr = *error_fr;
|
||||
*error_en_us = *error_en;
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
# Order of the constants:
|
||||
# * PE_OK 0
|
||||
# * PE_SESSIONEXPIRED 1
|
||||
|
@ -53,36 +58,36 @@ __END__
|
|||
|
||||
sub error_fr {
|
||||
[
|
||||
"Utilisateur authentifié",
|
||||
"Votre session a expiré, vous devez vous réauthentifier",
|
||||
"Identifiant ou mot de passe non renseigné",
|
||||
"Utilisateur authentifié",
|
||||
"Votre session a expiré, vous devez vous réauthentifier",
|
||||
"Identifiant ou mot de passe non renseigné",
|
||||
"Compte ou mot de passe LDAP de l'application incorrect",
|
||||
"Utilisateur inexistant",
|
||||
"Mot de passe ou identifiant incorrect",
|
||||
"Connexion impossible au serveur LDAP",
|
||||
"Erreur anormale du serveur LDAP",
|
||||
"Erreur du module Apache::Session choisi",
|
||||
"Authentification exigée",
|
||||
"Authentification exigée",
|
||||
"Certificat invalide",
|
||||
"Échec de l'initialisation de Lasso:Login ou Lasso:Logout",
|
||||
"Échec de la résolution de l'artefact Liberty Alliance",
|
||||
"Échec de la défédération Liberty Alliance",
|
||||
"La requête renvoyée par le fournisseur d'identité Liberty Alliance est vide",
|
||||
"Un des appels SOAP Liberty Alliance a échoué",
|
||||
"Un des appels de déconnexion Liberty Alliance a échoué",
|
||||
"Aucun artefact SAML trouvé, ou échec de l'auto-acceptation SSO",
|
||||
"Initialisation, construction ou requête SSO en échec",
|
||||
"Échec de l'initialisation de Lasso:Login ou Lasso:Logout",
|
||||
"Échec de la résolution de l'artefact Liberty Alliance",
|
||||
"Échec de la défédération Liberty Alliance",
|
||||
"La requête renvoyée par le fournisseur d'identité Liberty Alliance est vide",
|
||||
"Un des appels SOAP Liberty Alliance a échoué",
|
||||
"Un des appels de déconnexion Liberty Alliance a échoué",
|
||||
"Aucun artefact SAML trouvé, ou échec de l'auto-acceptation SSO",
|
||||
"Initialisation, construction ou requête SSO en échec",
|
||||
"Impossible d'enregistrer l'identifiant de connexion Liberty Alliance",
|
||||
"Un processus terminal Liberty Alliance a échoué",
|
||||
"Votre compte est bloqué",
|
||||
"Votre mot de passe a expiré",
|
||||
"Certificat exigé",
|
||||
"Un processus terminal Liberty Alliance a échoué",
|
||||
"Votre compte est bloqué",
|
||||
"Votre mot de passe a expiré",
|
||||
"Certificat exigé",
|
||||
];
|
||||
}
|
||||
|
||||
sub error_en {
|
||||
[
|
||||
"Everything is OK",
|
||||
"User authenticated",
|
||||
"Your connection has expired; You must to be authentified once again",
|
||||
"User and password fields must be filled",
|
||||
"Wrong directory manager account or password",
|
||||
|
@ -109,3 +114,31 @@ sub error_en {
|
|||
];
|
||||
}
|
||||
|
||||
sub error_ro {
|
||||
[
|
||||
"Utilizator autentificat",
|
||||
"Sesiunea dvs. a expirat, trebuie să vă reautentificaţi",
|
||||
"Identificator sau parolă inexistentă",
|
||||
"Cont sau parolă LDAP a aplicaţiei incorect",
|
||||
"Utilizator inexistent",
|
||||
"Parolă sau identificator incorect",
|
||||
"Conexiune imposibilă la serverul LDAP",
|
||||
"Eroare anormală a serverului LDAP",
|
||||
"Eroare a modulului Apache::Session aleasă",
|
||||
"Autentificare cerută",
|
||||
"Certificat invalid",
|
||||
"Eşec al iniţializării Lasso:Login sau Lasso:Logout",
|
||||
"Eşec al rezoluţiei artefact-ului Liberty Alliance",
|
||||
"Eşec al defederaţiei Liberty Alliance",
|
||||
"Cererea retrimisă de către furnizorul de identitate Liberty Alliance este goală",
|
||||
"Unul dintre apelurile SOAP Liberty Alliance a eşuat",
|
||||
"Unul dintre apelurile de deconectare Liberty Alliance a eşuat",
|
||||
"Nici un artefact SAML găsit, sau eşec al auto-acceptării SSO",
|
||||
"Iniţiere, construcţie sau cerere SSO în eşec",
|
||||
"Imposibil de a înregistra identificatorul de conectare Liberty Alliance",
|
||||
"Un proces terminal Liberty Alliance a eşuat",
|
||||
"Contul dvs. este blocat",
|
||||
"Parola dvs. a expirat",
|
||||
"Certificat cerut",
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user