| Lemonldap-NG-Handler documentation | Contained in the Lemonldap-NG-Handler distribution. |
Lemonldap::NG::Handler::AuthBasic - Perl extension to be able to authenticate users by basic web system but to use Lemonldap::NG to control authorizations.
Create your own package:
package My::Package;
use Lemonldap::NG::Handler::AuthBasic;
# IMPORTANT ORDER
our @ISA = qw (Lemonldap::NG::Handler::AuthBasic);
__PACKAGE__->init ( {
# Local storage used for sessions and configuration
localStorage => "Cache::DBFile",
localStorageOptions => {...},
# How to get my configuration
configStorage => {
type => "DBI",
dbiChain => "DBI:mysql:database=lemondb;host=$hostname",
dbiUser => "lemonldap",
dbiPassword => "password",
}
# Uncomment this to activate status module
# status => 1,
} );
Call your package in <apache-directory>/conf/httpd.conf
PerlRequire MyFile PerlHeaderParserHandler My::Package
This library provides a way to use Lemonldap::NG to manage authorizations without using Lemonldap::NG for authentications. This can be used in conjunction with a normal Lemonldap::NG installation but to manage non-browser clients.
Lemonldap::NG::Handler(3), http://lemonldap-ng.org/
Xavier Guimard, <x.guimard@free.fr>
Use OW2 system to report bug or ask for features: http://jira.ow2.org
Lemonldap::NG is available at http://forge.objectweb.org/project/showfiles.php?group_id=274
Copyright (C) 2008, 2010 by Xavier Guimard <x.guimard@free.fr>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available.
| Lemonldap-NG-Handler documentation | Contained in the Lemonldap-NG-Handler distribution. |
##@file # Auth-basic authentication with Lemonldap::NG rights management ##@class # Auth-basic authentication with Lemonldap::NG rights management package Lemonldap::NG::Handler::AuthBasic; use strict; use Lemonldap::NG::Handler::SharedConf qw(:all); use Digest::MD5 qw(md5_base64); use MIME::Base64; use SOAP::Lite; # link protected portalRequest use base qw(Lemonldap::NG::Handler::SharedConf); use utf8; no utf8; our $VERSION = '1.0.0'; # We need just this constant, that's why Portal is 'required' but not 'used' *PE_OK = *Lemonldap::NG::Portal::SharedConf::PE_OK; # Apache constants BEGIN { if ( MP() == 2 ) { *AUTH_REQUIRED = \&Apache2::Const::AUTH_REQUIRED; require Apache2::Access; } elsif ( MP() == 0 ) { eval 'sub AUTH_REQUIRED {1}'; } } ## @rmethod int run(Apache2::RequestRec apacheRequest) # overload run subroutine to implement Auth-Basic mechanism. # @param $apacheRequest current request # @return Apache constant sub run ($$) { my $class; ( $class, $apacheRequest ) = splice @_; if ( time() - $lastReload > $reloadTime ) { unless ( my $tmp = $class->testConf(1) == OK ) { $class->lmLog( "$class: No configuration found", 'error' ); return $tmp; } } return DECLINED unless ( $apacheRequest->is_initial_req ); my $uri = $apacheRequest->uri . ( $apacheRequest->args ? "?" . $apacheRequest->args : "" ); # AUTHENTICATION # I - recover the WWW-Authentication header my ( $id, $user, $pass ); unless ( $user = lmHeaderIn( $apacheRequest, 'Authorization' ) ) { lmSetErrHeaderOut( $apacheRequest, 'WWW-Authenticate' => 'Basic realm="Lemonldap::NG"' ); return AUTH_REQUIRED; } $user =~ s/^Basic\s*//; # DEBUG $class->lmLog( "debug : $user", 'notice' ); $id = md5_base64($user); # II - recover the user datas # 2.1 search if the user was the same as previous (very efficient in # persistent connection). unless ( $id eq $datas->{_session_id} ) { # 2.2 search in the local cache if exists unless ( $refLocalStorage and $datas = $refLocalStorage->get($id) ) { # 2.3 Authentication by Lemonldap::NG::Portal using SOAP request my $soap = SOAP::Lite->proxy( $class->portal() ) ->uri('urn:Lemonldap::NG::Common::CGI::SOAPService'); $user = decode_base64($user); ( $user, $pass ) = ( $user =~ /^(.*?):(.*)$/ ); my $r = $soap->getCookies( $user, $pass ); my $cv; # Catch SOAP errors if ( $r->fault ) { return $class->abort( "SOAP request to the portal failed: " . $r->fault->{faultstring} ); } else { my $res = $r->result(); # If authentication failed, display error if ( $res->{error} ) { $class->lmLog( "Authentication failed for $user " . $soap->error( 'fr', $res->{error} )->result(), 'notice' ); return AUTH_REQUIRED; } $cv = $res->{cookies}->{$cookieName}; } # Now, normal work to find session my %h; eval { tie %h, $globalStorage, $cv, $globalStorageOptions; }; if ($@) { # The cookie isn't yet available $class->lmLog( "The cookie $cv isn't yet available: $@", 'info' ); $class->updateStatus( $apacheRequest->connection->remote_ip, $apacheRequest->uri, 'EXPIRED' ); return $class->goToPortal($uri); } $datas->{$_} = $h{$_} foreach ( keys %h ); # Store now the user in the local storage if ($refLocalStorage) { $refLocalStorage->set( $id, $datas, "20 minutes" ); } untie %h; } } # ACCOUNTING # 1 - Inform Apache $class->lmSetApacheUser( $apacheRequest, $datas->{$whatToTrace} ); # AUTHORIZATION return $class->forbidden($uri) unless ( $class->grant($uri) ); $class->updateStatus( $datas->{$whatToTrace}, $apacheRequest->uri, 'OK' ); $class->logGranted($uri); # ACCOUNTING # 2 - Inform remote application $class->sendHeaders; # SECURITY # Hide Lemonldap::NG cookie $class->hideCookie; # Hide user password lmSetHeaderIn( $apacheRequest, Authorization => '' ); OK; } 1; __END__