JackAdams / meteor-accounts-ldap

Authentication against an LDAP server in Meteor
MIT License
21 stars 12 forks source link

Use with openLDAP #22

Open aessig opened 7 years ago

aessig commented 7 years ago

I can't figure out how to connect to openLDAP. I'm currently using this docker image (https://github.com/osixia/docker-openldap) to create a openldap server. I can connect to and create user using jxplorer but I can't figure out how to connect to it with meteor.

Here is my meteor configuration:

"serverDn": "OU=dep,DC=example,DC=org", "serverUrl": "ldap://192.168.99.100:389", "whiteListedFields": [ "displayName", "givenName", "memberOf", "initials"], "autopublishFields": [ "displayName" ], "searchField": "email", "searchValueType": "email"

and my LDAP Structure

And I try to login with users and it's password as credentials elements. Email is set to user@example.org

JackAdams commented 7 years ago

I'm sorry. I don't know what to suggest. Assuming your ip address and port are correct, everything else looks correct.

Are there any error messages in the console?

aessig commented 7 years ago

Just that: LDAP bind failed with error {"dn":"","code":34,"name":"InvalidDnSyntaxError","message":"invalid DN"}

How is the connection to the LDAP done ? Using the email address or a complete dn name ? like cn=user,cn=group,ou=dep,dc=example,dc=org , because using ldapwhoami I have a successful response.

JackAdams commented 7 years ago

This is a serverDn that works for one of the apps I'm working on:

OU=WAB_Active,DC=wab,DC=edu

I'm sorry, I have to confess I really know very little about the LDAP protocol and how connections are made. I adapted this package from an existing package that did all the things with LDAP that I didn't understand, but didn't do enough of the things I needed it to for a tight integration with accounts-password (those are the bits I added).

dalareo commented 7 years ago

Hi! I am also dealing with OpenLDAP connection and get:

I20170803-13:21:26.501(2)? LDAP authentication for: david
I20170803-13:21:26.505(2)? Trying to bind david...
I20170803-13:21:26.626(2)? Callback from binding LDAP:
I20170803-13:21:26.628(2)? {"dn":"","code":34,"name":"InvalidDnSyntaxError","message":"invalid DN"}
I20170803-13:21:26.629(2)? LDAP bind failed with error
I20170803-13:21:26.631(2)? {"dn":"","code":34,"name":"InvalidDnSyntaxError","message":"invalid DN"}

I modified LDAP.bindValue in order not to use @ and FQDN as default but getting the same error.

JackAdams commented 7 years ago

I'd happily accept a PR if you can find a fix, but I don't really know where to start trying to diagnose something like this. I'm out of my depth when it comes to dealing with LDAP connections. (My code contributions to the package were all about getting a tight integration with Meteor accounts.)

dalareo commented 7 years ago

Could you provide a working (with this package) LDAP directory to test against and debug the errors I am getting?

JackAdams commented 7 years ago

The ones I use this package with are active directories, maintained on-premise by schools. I can't really provide access to those and don't know how to set one up myself. The ldapjs docs have something about setting up a basic LDAP directory server.

dalareo commented 7 years ago

I do have already an OpenLDAP directory working, and connecting to other clients (Nextcloud, Gogs, Wordpress...). I guess the problem is the type of connection we are establishing with LDAP server, because, as fas as I can understand the connection is with an anonymous bind, and my server requires authorization with a bind user. If I modify LDAP.bind to include

LDAP.bindValue = function (usernameOrEmail, isEmailAddress, FQDN) {
       return ((isEmailAddress) ? usernameOrEmail : 'cn=' + usernameOrEmail + ',cn=users,ou=groups,dc=domain,dc=tld');
 }

I get: "error: no such object"

Which is the same error I get if I try to use ldapsearch from my command line with simple authentication.

JackAdams commented 7 years ago

This package depends on ldapjs. If there's anything in there that gives a clue how to use it to do authorization with a bind user, I'd happily accept a PR that gives package users that option.

I don't really have a good working knowledge of how this package retrieves the data from an LDAP directory/server. I do know that users need to supply their correct username and password for their info to be retrieved from the directory (in the few instances where I've used this package). Whether those login details are used for the bind part or not, I have to confess that, again, I don't know.

Sorry, I wish I could be more helpful.

dalareo commented 7 years ago

I solved it adding also:

LDAP.filter = function (isEmailAddress, usernameOrEmail, FQDN) { return '(&(' + ((isEmailAddress) ? 'mail' : 'cn') + '=' +          usernameOrEmail + ')(objectClass=inetOrgPerson))'; }

because at OpenLDAP objectClass is inetOrgPerson and setting serverDn as my user (cn=username,cn=users,ou=groups,dc=domain,dc=tld), the same vale as LDAP.bindValue as long as my OpenLDAP installation only supports single authentication. But now I need to set it so it uses a serverDn value depending on the username put in the user sign-in form. Any help, @JackAdams ?

The question is: how to create serverDn value programmatically??

JackAdams commented 7 years ago

Ah... now that's the sort of thing this package is made for. There should be a way.

On the server, overwrite:

LDAP.generateSettings = function (request) {
  return null;  
}

The request object should have a username property.

Take a look at the example at the bottom of the docs.

dalareo commented 7 years ago

Solved using:

 LDAP.generateSettings = function (request) {
     return { 
         'serverDn': 'CN=' + request.username + ',CN=users,OU=groups,DC=domain,DC=tld',
         '...',
         '...',
         };
 }