Mailing List Archive

Trouble using Authentication::Store::LDAP
Hello all,

I am trying to get LDAP authentication (Open directory) going with a catalyst application.

I can connect to LDAP and run a query through NET::LDAP like so:

--------------------------------------------------------------------------------------------
my $domain = "ldap://od.someplace.edu";

my $ldap = Net::LDAP->new( $domain ) or die print "$@\n";

$mesg = $ldap->bind();

$mesg = $ldap->search( base => "cn=users,dc=someplace,dc=edu",
filter=>"(uid=auser)",
) or die print "$@\n";

---------------------------------------------------------------------------------------------

However, if I try to bind with a particular username and password

$ldap->bind("user", "password");

I get an error message: "No AUTH supplied".

I can also run a query using ldapsearch

----------------------------------------------------------------------------------------
ldapsearch -H ldap://od.someplacel.edu -x -b "cn=groupname,cn=groups,dc=someplace,dc=edu"
----------------------------------------------------------------------------------------

Here's is the MyApp.yml

-----------------------------------------------------------------------------------------

authentication:
default_realm: ldap
realms:
ldap:
credential:
class: Password
password_field: userPassword
store:
binddn: anonymous
bindpw: dontcarehow
class: LDAP
ldap_server: od.someplace.edu
ldap_server_options:
onerror: warn
timeout: 30
start_tls: 0
user_basedn: cn=users,dc=someplace,dc=edu
user_field: uid
user_filter: (&(objectClass=posixAccount)(uid=%s))
user_scope: sub
user_search_options:
deref: always
use_roles: 0
#role_basedn: cn=groups,dc=qatar-med,dc=cornell,dc=edu
#role_filter: (&(objectClass=inetOrgPerson)(memberUid=%s))
#role_scope: one
#role_field: uid
#role_value: dn
#role_search_options:
#deref: always

--------------------------------------------------------------------------------------

The password field is defined userPassword.

I have tried having the ldap_server be ldap://od.someplace.edu
Also instead binddn/bindpw being anonymous/dontcarehow I have tried setting them to a valid username/password

I would like to get roles going as well, but for right now I would like to just authenticate a single user.

My controller Login.pm looks like this:
-----------------------------------------------------------------------------------

sub index :Path :Args(0) {
my ( $self, $c ) = @_;

if ( my $user = $c->req->params->{username} and my $password = $c->req->params->{password} ){

if ( $c->authenticate( { id => $user, password => $password } ) ) {
$c->res->body( "hello " . $c->user->get("name") );
}
else{
# login incorrect
$c->stash(error => "Login is incorrect. Please try again");
$c->stash(template => 'login/login.tt2');
}
}
else {
$c->stash(error => "Invalid form input");
$c->stash(template => 'login/login.tt2');
}

$c->stash(template => 'login/login.tt2');
}

------------------------------------------------------------------------------

In the catalyst debug menu I get the correct form submission, but each time it fails the authentication step and displaying the "login is incorrect" message. There is no other output in the debugger.

I believe it is connecting. I can do something to put in a typo so I get an error stating 'Invalid credentials' or else an SSL timeout error. This doesn't get me any error messages, but its not authenticating a valid user either.

Any ideas for me?

Best,
Jillian
_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Trouble using Authentication::Store::LDAP [ In reply to ]
On 10 April 2013 13:46, Jillian Rowe <jir2004@qatar-med.cornell.edu> wrote:

> Hello all,
>
> I am trying to get LDAP authentication (Open directory) going with a
> catalyst application.
>
> I can connect to LDAP and run a query through NET::LDAP like so:
> [snip]
>
> However, if I try to bind with a particular username and password
>
> $ldap->bind("user", "password");
>
> I get an error message: "No AUTH supplied".
>

So firstly, if you can't get the authentication working outside Catalyst,
using Net::LDAP alone (and clearly you can't) then this isn't a Catalyst
issue!
Secondly, the docs say you should pass a "bind DN" and not a simple
username. For example $ldap->bind("cn=someusername,o=University of
Nowhere,c=US", $password) seems more likely to work.

Get the auth credentials working standalone and then worry about the
Catalyst integration...

/joel
Re: Trouble using Authentication::Store::LDAP [ In reply to ]
On 10/04/13 12:46, Jillian Rowe wrote:

> Here's is the MyApp.yml
> authentication:
> default_realm: ldap
> realms:
> ldap:
> credential:
> class: Password
> password_field: userPassword
> My controller Login.pm looks like this:
> if ( $c->authenticate( { id => $user, password => $password } ) ) {

If memory serves the password_field value should be password so that it
matches the user info key passed to the authenticate method

--

Regards

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
RE: Trouble using Authentication::Store::LDAP [ In reply to ]
Hi again,

Thanks for the tip about the binddn! I'm completely new to authentication.

[snip]
So firstly, if you can't get the authentication working outside Catalyst, using Net::LDAP alone (and clearly you can't) then this isn't a Catalyst issue!
Secondly, the docs say you should pass a "bind DN" and not a simple username. For example $ldap->bind("cn=someusername,o=University of Nowhere,c=US", $password) seems more likely to work.
[snip]

Now I've got the binding going in both ldapsearch and Net::LDAP, but I'm still having trouble with catalyst.

------------------------------------------------------------------------------------------------------------------------------------------------------
use Net::LDAP;

my $USERNAME = 'auser';
my $PASSWORD = 'secret';
my $LDAP_SERVER = "ldap://od.someplace.edu";
my $LDAP_PORT = '389';
my $LDAP_BASE = 'cn=users,dc=someplace,dc=edu';

my $userDN = "uid=$USERNAME,cn=users,dc=someplace,dc=edu";

$ldap = Net::LDAP->new($LDAP_SERVER, port => $LDAP_PORT) or die "Coult not create LDAP object\n";

$ldapMsg = $ldap->bind($userDN, password => $PASSWORD);

die $ldapMsg->error if $ldapMsg->is_error;

my $ldapSearch = $ldap->search(base => $LDAP_BASE,
filter => "uid=$USERNAME");

die "There was an error during search:\n\t" . ldap_error_text($ldapSearch->code)
if $ldapSearch->code;

print "Results returned: ".$ldapSearch->count."\n";
print "No results returned\n" and exit
if( (!$ldapSearch) || ($ldapSearch->count == 0) );
----------------------------------------------------------------------------------------------------------------------------------------------------

This tells me that one result is returned, which is correct.

----------------------------------------------------------------------------------------------------------------------------------------------------

ldapsearch

ldapsearch -H ldap://od.someplace.edu -b "cn=users,dc=someplace,dc=edu" -D "uid=auser,cn=users,dc=someplace,dc=edu" -W
----------------------------------------------------------------------------------------------------------------------------------------------------

Also works as expected.

----------------------------------------------------------------------------------------------------------------------------------------------------
MyApp.yml

authentication:
default_realm: ldap
realms:
ldap:
credential:
class: Password
password_field: password
store:
binddn: uid=auser,cn=users,dc=someplace,dc=edu
bindpw: secret
class: LDAP
ldap_server: ldap://od.someplace.edu
ldap_server_options:
onerror: warn
timeout: 30
start_tls: 0
user_basedn: cn=users,dc=someplace,dc=edu
user_field: uid
user_filter: (&(objectClass=posixAccount)(uid=%s))
user_scope: sub
user_search_options:
deref: always
use_roles: 0

----------------------------------------------------------------------------------------------------------------------------------------------------

The login is still not working, and also not giving any errors!


Best,
Jillian
_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
RE: Trouble using Authentication::Store::LDAP [ In reply to ]
Hello all,

So after much bungling of source code by adding in Catalyst::Exception->throw(Dumper(whatever)) I have figured out it is binding to ldap correctly, and it is fetching the correct user information. The catch is in the password, which I still haven't figured out.

I did figure out in my conf file the password_field should be userpassword so it matches the ldap entry. Same for the controller.

---------------------------------------------------------
authentication:
default_realm: ldap
realms:
ldap:
credential:
class: Password
password_field: userpassword
password_type: crypted
password_hash_type: MD5
store:
binddn: anonymous
bindpw: dontcarehow
class: LDAP
ldap_server: ldap://od.qatar-med.cornell.edu
ldap_server_options:
onerror: warn
timeout: 30
start_tls: 0
use_roles: 0
user_basedn: cn=users,dc=qatar-med,dc=cornell,dc=edu
user_field: uid
user_filter: (&(objectClass=posixAccount)(uid=%s))
user_scope: sub
user_search_options:
deref: always
--------------------------------------------------

$c->authenticate( {id => $user, userpassword => $password} );

-------------------------------------------------

Where its failing is in Authentication::Credential::Password. It doesn't look as if I'm getting the right password type. It shows up as just '********' from the ldap entry.

I also noticed in Authentication::Credential::Password it is deleting the password in stored from the webform login info.

-------------------------------------------

sub authenticate {
my ( $self, $c, $realm, $authinfo ) = @_;

## because passwords may be in a hashed format, we have to make sure that we remove the
## password_field before we pass it to the user routine, as some auth modules use
## all data passed to them to find a matching user...
$c->log->debug("In Authentication::Credential::Password");

my $userfindauthinfo = {%{$authinfo}};

# die $c->log->debug("User info is: ".Dumper($userfindauthinfo));

delete($userfindauthinfo->{$self->_config->{'password_field'}}); <------------------------------------Deleting here

my $user_obj = $realm->find_user($userfindauthinfo, $c);
$c->log->debug("User is ".Dumper($user_obj));

if (ref($user_obj)) {
if ($self->check_password($c, $user_obj, $authinfo)) {
$c->log->debug("Check password returned as true");
return $user_obj;
}
else{
$c->log->debug("Password type probably incorrect");
}
} else {
$c->log->debug(
'Unable to locate user matching user info provided in realm: '
. $realm->name
) if $c->debug;
return;
}
}

Then where it checks the password

sub check_password {
my ( $self, $c, $user, $authinfo ) = @_;

$c->log->debug("Password type is: ".$self->_config->{'password_type'});

if ($self->_config->{'password_type'} eq 'self_check') {
return $user->check_password($authinfo->{$self->_config->{'password_field'}});
} else {
my $password = $authinfo->{$self->_config->{'password_field'}};
my $storedpassword = $user->get($self->_config->{'password_field'});

... and so on. It should be getting the password from $authinfo->{$self->_config->{'password_field'}, but it is deleting it in previously and it comes up as undef. If I comment out the line at least it isn't undef, but I am still getting stuck on the password type.

---------------------------------------------------------------------------------------------------------------

Does anyone have any tips on possible combinations of password types I could try?

Best,
Jillian

P.S. It would be nice if there were more debugging messages in the Password module. I went and added these all in by hand, but in general I prefer not to change source code. :)

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Trouble using Authentication::Store::LDAP [ In reply to ]
On 15 Apr 2013, at 07:41, Jillian Rowe <jir2004@qatar-med.cornell.edu> wrote:

> Hello all,
>
> So after much bungling of source code by adding in Catalyst::Exception->throw(Dumper(whatever)) I have figured out it is binding to ldap correctly, and it is fetching the correct user information. The catch is in the password, which I still haven't figured out.
>
> I did figure out in my conf file the password_field should be userpassword so it matches the ldap entry. Same for the controller.
>
> ---------------------------------------------------------
> authentication:
> default_realm: ldap
> realms:
> ldap:
> credential:
> class: Password
> password_field: userpassword
> password_type: crypted
> password_hash_type: MD5


You want password_type: self_check
>
> Does anyone have any tips on possible combinations of password types I could try?
>

LDAP works somewhat differently to other stores..

What happens is:

. Connect to LDAP server
. Search for user
. Re-connect (i.e. bind) to LDAP server as that user, with that user's password

At this point, you've verified that the user's password is ok.. There doesn't need to be another step!

Thus if you use self_check, then the LDAP user class will just say 'yes', as the user is already authenticated..

> P.S. It would be nice if there were more debugging messages in the Password module. I went and added these all in by hand, but in general I prefer not to change source code. :)

You're right - I've just never succeeded at writing any debug messages which would actually make sense or help with debugging this without also reading the code side-by-side.

I'd love a patch which attempted to do this however!

Cheers
t0m


_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
RE: Trouble using Authentication::Store::LDAP [ In reply to ]
Thanks, t0m! It works with the self_check password_type.

So all in all the things I learned are that the password_field has to match what is actually in your ldap in both the config file (with all the authentication info) and in the controller.

The credential: password_field should be userpassword for me, and in my controller $c->authenticate({id => $username, userpassword => $password})

Although when I do an ldap search it comes out as userPassword, it still needs to be lowercase.

Thanks for the help!

________________________________________
From: Tomas Doran [bobtfish@bobtfish.net]
Sent: Monday, April 15, 2013 2:48 PM
To: Development of the elegant MVC web framework
Subject: Re: [Catalyst-dev] Trouble using Authentication::Store::LDAP

On 15 Apr 2013, at 07:41, Jillian Rowe <jir2004@qatar-med.cornell.edu> wrote:

> Hello all,
>
> So after much bungling of source code by adding in Catalyst::Exception->throw(Dumper(whatever)) I have figured out it is binding to ldap correctly, and it is fetching the correct user information. The catch is in the password, which I still haven't figured out.
>
> I did figure out in my conf file the password_field should be userpassword so it matches the ldap entry. Same for the controller.
>
> ---------------------------------------------------------
> authentication:
> default_realm: ldap
> realms:
> ldap:
> credential:
> class: Password
> password_field: userpassword
> password_type: crypted
> password_hash_type: MD5


You want password_type: self_check
>
> Does anyone have any tips on possible combinations of password types I could try?
>

LDAP works somewhat differently to other stores..

What happens is:

. Connect to LDAP server
. Search for user
. Re-connect (i.e. bind) to LDAP server as that user, with that user's password

At this point, you've verified that the user's password is ok.. There doesn't need to be another step!

Thus if you use self_check, then the LDAP user class will just say 'yes', as the user is already authenticated..

> P.S. It would be nice if there were more debugging messages in the Password module. I went and added these all in by hand, but in general I prefer not to change source code. :)

You're right - I've just never succeeded at writing any debug messages which would actually make sense or help with debugging this without also reading the code side-by-side.

I'd love a patch which attempted to do this however!

Cheers
t0m


_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Trouble using Authentication::Store::LDAP [ In reply to ]
On 17 Apr 2013, at 08:25, Jillian Rowe <jir2004@qatar-med.cornell.edu> wrote:

> Thanks, t0m! It works with the self_check password_type.
>
> So all in all the things I learned are that the password_field has to match what is actually in your ldap in both the config file (with all the authentication info) and in the controller.
>
> The credential: password_field should be userpassword for me, and in my controller $c->authenticate({id => $username, userpassword => $password})
>
> Although when I do an ldap search it comes out as userPassword, it still needs to be lowercase.
>
> Thanks for the help!


Yay! Glad you got it figured out.

In future, you're probably better with this sort of list on the Catalyst users list - this list is generally used for the development of Catalyst itself (and is much lower traffic, so less eyes).

And hmm, you're probably right about the ldap search values required - this possibly / probably could be fixed, and/or the docs for the LDAP store should be improved to better note that you need to use 'self_check'. Can you log a bug with as much info as possible against that module so this doesn't get lost? (https://rt.cpan.org/Public/Dist/Display.html?Name=Catalyst-Authentication-Store-LDAP)

Cheers
t0m


_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev