1package Authen::Simple::ActiveDirectory; 2 3use strict; 4use warnings; 5use base 'Authen::Simple::Adapter'; 6 7use Net::LDAP qw[]; 8use Net::LDAP::Constant qw[LDAP_INVALID_CREDENTIALS]; 9use Params::Validate qw[]; 10 11our $VERSION = 0.3; 12 13__PACKAGE__->options({ 14 host => { 15 type => Params::Validate::SCALAR | Params::Validate::ARRAYREF, 16 default => 'localhost', 17 optional => 1 18 }, 19 port => { 20 type => Params::Validate::SCALAR, 21 default => 389, 22 optional => 1 23 }, 24 timeout => { 25 type => Params::Validate::SCALAR, 26 default => 60, 27 optional => 1 28 }, 29 principal => { 30 type => Params::Validate::SCALAR, 31 optional => 0 32 } 33}); 34 35sub check { 36 my ( $self, $username, $password ) = @_; 37 38 my $connection = Net::LDAP->new( $self->host, 39 port => $self->port, 40 timeout => $self->timeout 41 ); 42 43 unless ( defined $connection ) { 44 45 my $host = $self->host; 46 47 $self->log->error( qq/Failed to connect to '$host'. Reason: '$@'/ ) 48 if $self->log; 49 50 return 0; 51 } 52 53 my $user = sprintf( '%s@%s', $username, $self->principal ); 54 my $message = $connection->bind( $user, password => $password ); 55 56 if ( $message->is_error ) { 57 58 my $error = $message->error; 59 my $level = $message->code == LDAP_INVALID_CREDENTIALS ? 'debug' : 'error'; 60 61 $self->log->$level( qq/Failed to authenticate user '$user'. Reason: '$error'/ ) 62 if $self->log; 63 64 return 0; 65 } 66 67 $self->log->debug( qq/Successfully authenticated user '$user'./ ) 68 if $self->log; 69 70 return 1; 71} 72 731; 74 75__END__ 76 77=head1 NAME 78 79Authen::Simple::ActiveDirectory - Simple ActiveDirectory authentication 80 81=head1 SYNOPSIS 82 83 use Authen::Simple::ActiveDirectory; 84 85 my $ad = Authen::Simple::ActiveDirectory->new( 86 host => 'ad.company.com', 87 principal => 'company.com' 88 ); 89 90 if ( $ad->authenticate( $username, $password ) ) { 91 # successfull authentication 92 } 93 94 # or as a mod_perl Authen handler 95 96 PerlModule Authen::Simple::Apache 97 PerlModule Authen::Simple::ActiveDirectory 98 99 PerlSetVar AuthenSimpleActiveDirectory_host "ad.company.com" 100 PerlSetVar AuthenSimpleActiveDirectory_principal "company.com" 101 102 <Location /protected> 103 PerlAuthenHandler Authen::Simple::ActiveDirectory 104 AuthType Basic 105 AuthName "Protected Area" 106 Require valid-user 107 </Location> 108 109=head1 DESCRIPTION 110 111Authenticate against Active Directory. 112 113This implementation differs from L<Authen::Simple::LDAP> in way that it will 114try to bind directly as the users principial. 115 116=head1 METHODS 117 118=over 4 119 120=item * new 121 122This method takes a hash of parameters. The following options are 123valid: 124 125=over 8 126 127=item * host 128 129Connection host, can be a hostname, IP number or a URI. Defaults to C<localhost>. 130 131 host => ldap.company.com 132 host => 10.0.0.1 133 host => ldap://ldap.company.com:389 134 host => ldaps://ldap.company.com 135 136=item * port 137 138Connection port, default to 389. May be overriden by host if host is a URI. 139 140 port => 389 141 142=item * timeout 143 144Connection timeout, defaults to 60. 145 146 timeout => 60 147 148=item * principal 149 150The suffix in users principal, usally the domain or forrest. Required. 151 152 principal => 'company.com' 153 154=item * log 155 156Any object that supports C<debug>, C<info>, C<error> and C<warn>. 157 158 log => Log::Log4perl->get_logger('Authen::Simple::ActiveDirectory') 159 160=back 161 162=item * authenticate( $username, $password ) 163 164Returns true on success and false on failure. 165 166=back 167 168=head1 SEE ALSO 169 170L<Authen::Simple::LDAP>. 171 172L<Authen::Simple>. 173 174L<Net::LDAP>. 175 176=head1 AUTHOR 177 178Christian Hansen C<chansen@cpan.org> 179 180=head1 COPYRIGHT 181 182This program is free software, you can redistribute it and/or modify 183it under the same terms as Perl itself. 184 185=cut 186