add LDAP authentication support
This commit is contained in:
@@ -8,7 +8,7 @@ use base 'Dancer::Plugin::Auth::Extensible::Provider::Base';
|
||||
# with thanks to yanick's patch at
|
||||
# https://github.com/bigpresh/Dancer-Plugin-Auth-Extensible/pull/24
|
||||
|
||||
use Dancer qw(:syntax);
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::DBIC;
|
||||
|
||||
use Digest::MD5;
|
||||
@@ -21,18 +21,6 @@ sub authenticate_user {
|
||||
return $self->match_password($password, $user);
|
||||
}
|
||||
|
||||
sub match_password {
|
||||
my( $self, $password, $user ) = @_;
|
||||
return unless $user and $password and $user->password;
|
||||
|
||||
my $settings = $self->realm_settings;
|
||||
my $password_column = $settings->{users_password_column} || 'password';
|
||||
|
||||
my $sum = Digest::MD5::md5_hex($password);
|
||||
return ($sum eq $user->$password_column ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
sub get_user_details {
|
||||
my ($self, $username) = @_;
|
||||
|
||||
@@ -69,4 +57,113 @@ sub get_user_roles {
|
||||
return [ $user->$roles->get_column( $role_column )->all ];
|
||||
}
|
||||
|
||||
sub match_password {
|
||||
my($self, $password, $user) = @_;
|
||||
return unless $user;
|
||||
|
||||
my $settings = $self->realm_settings;
|
||||
my $username_column = $settings->{users_username_column} || 'username';
|
||||
|
||||
return $user->ldap
|
||||
? $self->match_with_ldap($password, $user->$username_column)
|
||||
: $self->match_with_local_pass($password, $user);
|
||||
}
|
||||
|
||||
sub match_with_local_pass {
|
||||
my($self, $password, $user) = @_;
|
||||
|
||||
my $settings = $self->realm_settings;
|
||||
my $password_column = $settings->{users_password_column} || 'password';
|
||||
|
||||
return unless $password and $user->password_column;
|
||||
|
||||
my $sum = Digest::MD5::md5_hex($password);
|
||||
return ($sum eq $user->$password_column ? 1 : 0);
|
||||
}
|
||||
|
||||
sub match_with_ldap {
|
||||
my($self, $pass, $user) = @_;
|
||||
|
||||
eval 'require Net::LDAP';
|
||||
if ($@) {error $@; return}
|
||||
|
||||
return unless setting('ldap') and ref {} eq ref setting('ldap');
|
||||
my $conf = setting('ldap');
|
||||
|
||||
my $ldapuser = $conf->{user_string};
|
||||
$ldapuser =~ s/\%USER\%?/$user/egi;
|
||||
|
||||
# If we can bind as anonymous or proxy user,
|
||||
# search for user's distinguished name
|
||||
if ($conf->{proxy_user}) {
|
||||
my $user = $conf->{proxy_user};
|
||||
my $pass = $conf->{proxy_pass};
|
||||
my $attrs = ['distinguishedName'];
|
||||
my $result = _ldap_search($ldapuser, $attrs, $user, $pass);
|
||||
$ldapuser = $result->[0] if ($result->[0]);
|
||||
}
|
||||
# otherwise, if we can't search and aren't using AD and then construct DN by
|
||||
# appending base
|
||||
elsif ($ldapuser =~ m/=/) {
|
||||
$ldapuser = "$ldapuser,$conf->{base}";
|
||||
}
|
||||
|
||||
foreach my $server (@{$conf->{servers}}) {
|
||||
my $opts = $conf->{opts} || {};
|
||||
my $ldap = Net::LDAP->new($server, %$opts) or next;
|
||||
my $msg = undef;
|
||||
|
||||
if ($conf->{tls_opts} ) {
|
||||
$msg = $ldap->start_tls(%{$conf->{tls_opts}});
|
||||
}
|
||||
|
||||
$msg = $ldap->bind($ldapuser, password => $pass);
|
||||
$ldap->unbind(); # take down session
|
||||
|
||||
return 1 unless $msg->code();
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub _ldap_search {
|
||||
my ($filter, $attrs, $user, $pass) = @_;
|
||||
|
||||
return undef unless defined($filter);
|
||||
return undef if (defined $attrs and ref [] ne ref $attrs);
|
||||
|
||||
return unless setting('ldap') and ref {} eq ref setting('ldap');
|
||||
my $conf = setting('ldap');
|
||||
|
||||
foreach my $server (@{$conf->{server}}) {
|
||||
my $opts = $conf->{opts} || {};
|
||||
my $ldap = Net::LDAP->new($server, %$opts) or next;
|
||||
my $msg = undef;
|
||||
|
||||
if ($conf->{tls_opts}) {
|
||||
$msg = $ldap->start_tls(%{$conf->{tls_opts}});
|
||||
}
|
||||
|
||||
if ( $user and $user ne 'anonymous' ) {
|
||||
$msg = $ldap->bind($user, password => $pass);
|
||||
}
|
||||
else {
|
||||
$msg = $ldap->bind();
|
||||
}
|
||||
|
||||
$msg = $ldap->search(
|
||||
base => $conf->{base},
|
||||
filter => "($filter)",
|
||||
attrs => $attrs,
|
||||
);
|
||||
|
||||
$ldap->unbind(); # take down session
|
||||
|
||||
my $entries = [$msg->entries];
|
||||
return $entries unless $msg->code();
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Reference in New Issue
Block a user