Hey,

now I found the error.

The module works fine, but in our ldap installation we don’t have displayName attribute for the entries.
I had to set the name_attribute: ‘cn’ in the config.yml.
Now it works fine.

Thanks for the help

Best regards,
Attila

On 2018. Oct 10., at 20:40, Attila Bárdi <attila.bardi@gmail.com> wrote:

Hey Alex

well, my usecase is to allow user to login to the webapp, and after that they can change some attributes of theirs.
I don’t want to deal with groups (yet), maybe later.

On 2018. Oct 10., at 18:06, Alex Mestiashvili <mailatgoogl@gmail.com> wrote:

Hi, 

On Wed, Oct 10, 2018 at 3:42 PM Attila Bárdi <attila.bardi@gmail.com> wrote:
Hey,

I used Ldap with Dancer and it works pretty fine. Now I want to develop a new microsite, I thought it would be better with Dancer2(0.206000). But I cannot make the Ldap (0.702) authentication to work.

I turned on the ldap logging. By the log It looks working, because it found the user, but the page says login failed. The second search for the groups has 0 match, the user doesn't member of any group. But I can log in with the user foo, and he is not a member of any group neither. The result is LOGIN FAILED.

As far as I understand You'd like role-based access control for your app, where roles are actually ldap groups. I.e. uid belongs to a group <=> has a role.
Now you have to decide what exactly will contain the roles. In unix a user can have 1 primary group and multiple secondary groups.
IMHO it is more flexible to check for members of the secondary groups, which may have the following format in case of openldap:

objectClass: posixGroup
displayName: powerusers
description: "members have role users"
gidNumber: 1001
cn: powerusers
memberUid: user1
memberUid: user2
memberUid: ...

If you'd like to check for the primary group then you'll probably will need to check for gidNumber.. 
 

In the Dancer2 log says:

Odd number of elements in anonymous hash at /usr/local/share/perl/5.24.1/Dancer2/Plugin/Auth/Extensible/Provider/LDAP.pm line 279.

OpenLdap log:

Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 fd=106 ACCEPT from IP=a.b.c.d:47724 (IP=0.0.0.0:389)
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=0 BIND dn="cn=Administrator,dc=gothamcity,dc=example,dc=com" method=128
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=0 BIND dn="cn=Administrator,dc=gothamcity,dc=example,dc=com" mech=SIMPLE ssf=0
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=0 RESULT tag=97 err=0 text=
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=1 SRCH base="dc=example,dc=com" scope=2 deref=2 filter="(&(objectClass=inetOrgPerson)(uid=battila))"
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=2 SRCH base="dc=example,dc=com" scope=2 deref=2 filter="(&(objectClass=groupOfNames)(member=uid=battila,ou=people,dc=gothamcity,dc=example,dc=com))"

This seem to be the problem, this LDAP plugin as far as I see is intended to be used with WindowsAD.
The searchfilter above is simply not applicable for your case. In case of openldap
 rolefilter would be rather memberUID: $uid instead of member=uid=$uid,ou=blabla,dc=….

This second part is gone since I did add: disable_roles: 1 to my config.

It is also hardcoded into the plugin:
Lines 256-264:
        # now get the roles
 
        $mesg = $ldap->search(
            base   => $self->basedn,
            filter => '(&'
              . $self->role_filter . '('
              . $self->role_member_attribute . '='
              . $entry->dn . '))',
        );
But the good thing is that you can simply change that :) 

Yes, I saw that. But I will deal with roles much later.



Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=2 SEARCH RESULT tag=101 err=0 nentries=0 text=
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 op=3 UNBIND
Oct 10 14:35:13 openldap01 slapd[991]: conn=674413 fd=106 closed

User entry in the openldap:

dn: uid=battila,ou=people,dc=gothamcity,dc=example,dc=com
cn: Attila Bardi
gidNumber: 1901
givenName: Attila
loginShell: /bin/bash
description: example
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
shadowInactive: -1
shadowLastChange: 14284
shadowMax: 99999
shadowMin: 0
shadowWarning: 7
sn: Bardi
uid: battila
uidNumber: 43821
homeDirectory: /home/battila
mail: battila@example.com
structuralObjectClass: inetOrgPerson
entryUUID: d3a89750-5a5e-1038-9b9a-dbf2c7148bb9
creatorsName: cn=Administrator,dc=gothamcity,dc=example,dc=com
createTimestamp: 20181002071629Z
userPassword:: e1e1ee1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e
entryCSN: 20181002075005.324787Z#000000#000#000000
modifiersName: uid=battila,ou=people,dc=gothamcity,dc=example,dc=com
modifyTimestamp: 20181002075005Z


Dancer2 config.yml
plugins:
       Auth::Extensible:
               realms:
                       config:
                               provider: Config
                               users:
                                       - user: 'foo'
                                         pass: 'secret'
                       users:
                               provider: LDAP
                               host:   'openldap01'
                               binddn: 'cn=Administrator,dc=gothamcity,dc=example,dc=com'
                               bindpw: 'secret'
                               basedn: 'dc=example,dc=com'
                               user_filter: '(objectClass=inetOrgPerson)'
                               username_attribute: "uid"

I tried disable_roles: 1 after this but the result is still LOGIN FAILED.


Another thing which in my opinion is plain wrong is that you need to provide admin binddn and bindpw.
In openldap world normally a user can bind itself and get all the necessary attributes.
Also in many setups it is just not secure to give admin access to ldap tree to a web app.

Here is the plugin for Dancer1 which works with openldap without admin access:

The ldap plugin I used for Dancer1 required the admin bind too. But for me it is ok, because this way I could add a functionality to add/disable/enable users from the web interface based on roles.
It is the Authen::Simple::LDAP, and it has way much better documentation the this Dancer2::Plugin::Auth::Extensible::Provider::LDAP.

May be it will give you some hints, though it is easier to fix the original Dancer2 plugin.

Yep, it seems to I have to dig deep into Daner2 plugin system to understand, then I can fix that LDAP modul.


Best, 
Alex

Best regards,
Attila