Dancer2 Dancer2::Plugin::Auth::Extensible::Provider::LDAP
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. 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))" 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. I tried to turn on debugging, as I saw the Dancer2::Plugin::Auth::Extensible::Provider::LDAP module has some messages sending with debug, but they haven't been displayed. log: 'core' startup_info: 1 show_errors: 1 logger: console What do I do wrong? Shall I go back to Dancer1? Thanks! Best regards, Attila
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=.... It is also hardcoded into the plugin: https://metacpan.org/source/SYSPETE/Dancer2-Plugin-Auth-Extensible-Provider-... 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 :)
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: https://pastebin.com/vy9ea9P8 May be it will give you some hints, though it is easier to fix the original Dancer2 plugin. Best, Alex
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 <mailto: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 <http://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: https://metacpan.org/source/SYSPETE/Dancer2-Plugin-Auth-Extensible-Provider-... <https://metacpan.org/source/SYSPETE/Dancer2-Plugin-Auth-Extensible-Provider-LDAP-0.702/lib/Dancer2/Plugin/Auth/Extensible/Provider/LDAP.pm> 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 <mailto: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: https://pastebin.com/vy9ea9P8 <https://pastebin.com/vy9ea9P8>
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
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 <mailto:mailatgoogl@gmail.com>> wrote:
Hi,
On Wed, Oct 10, 2018 at 3:42 PM Attila Bárdi <attila.bardi@gmail.com <mailto: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 <http://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: https://metacpan.org/source/SYSPETE/Dancer2-Plugin-Auth-Extensible-Provider-... <https://metacpan.org/source/SYSPETE/Dancer2-Plugin-Auth-Extensible-Provider-LDAP-0.702/lib/Dancer2/Plugin/Auth/Extensible/Provider/LDAP.pm> 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 <mailto: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: https://pastebin.com/vy9ea9P8 <https://pastebin.com/vy9ea9P8>
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
participants (2)
-
Alex Mestiashvili -
Attila Bárdi