LDAP auth options

I basically need to authenticate users against an LDAP server. Iā€™m not sure there is a fully developed AND secure package / means to do this yet. Iā€™d ideally like to not have to rip out my current accounts code. I recently installed the LDAP.js node package. Not super familiar with LDAP, but got the essential info from network admin. Advice for where to go from here?

1 Like

Same problem here. I have already tried the following packages without success:
babrahams:accounts-ldap
tdamsma:meteor-accounts-ldap
krt:accounts-ldap
typ:accounts-ldap

Iā€™ve got different errors using then, from ā€˜InvalidDnSyntaxErrorā€™ to ā€˜Future resolved more than onceā€™. Iā€™m sure that my LDAP parameters are correct since Iā€™m using them in PHP systems.

Somebody have some clue abouthow to get LDAP authentication working in Meteor?

Thanks in advance and sorry for my English,

Adilson Oliveira Cruz

@adilsonocruz Hi Adilson, I ended up using typ:accounts-ldap with success. You will likely need to create your own login template and then handle the loginWithLDAP method yourself. I suggest giving it another go. If you run into issues, post some code and Iā€™ll try to help. Eric Typaldos, the package author is also a very helpful guy.

1 Like

Hi benco ,
I need to establish ldap authentication for one of my project.
I tried to find an example to understand the concept.Could you give me some pointer or tutorial or any way point me in the right direction. I never heard of the ldap before this project come along

really appreciate any help I get

meteor add typ:accounts-ldap

Hereā€™s something to get you started or for reference use. I did this initially with Blaze and Meteor ~1.1, so translate as needed. Template JS below shows calling loginWithLDAP method. Create the html that this will utilize. Should be pretty evident from the JS whatā€™s needed.

I have not checked the accounts-ldap package readme recently so not sure what has changed, but you should read it and make sure itā€™s ok for your use case especially regarding security / encryption (or lack thereof). There might be better alternatives out there too now, so do your due diligence, etcā€¦ If using the package, Eric (typ; the package author) is helpful and responsive, so you can always ping him if needed.

Template.ldapLogin.events({
  'submit #login-form': function (e) {
    e.preventDefault();
    var form = $(e.target);
    var username = form.find("#login-form-username").val();
    var password = form.find("#login-form-password").val();

    if (username === "admin") {
      Meteor.loginWithPassword(username, password, function (error) {
        if ( ! error && password === "admin") {
          // Set switch to trigger alert to change password
          Session.setPersistent("passChangePrompt", 1);
        }
      });
    } else {
      Meteor.loginWithLDAP(username, password,
        { dn: "uid=" + username + ",ou=<foo>,dc=<bar>,dc=<baz>,dc=<qux>" },
        function (error, success) {
          if (error) {
            console.log(error.reason);
          } else {
            FlowRouter.redirect('/');
          };
      });
    }
  }
});

Server:

Meteor.startup( function() {
  LDAP_DEFAULTS.url = 'ldap://<ask your IT dude or gal>';
  LDAP_DEFAULTS.dn = 'ou=<foo>,dc=<bar>,dc=<baz>,dc=<qux>';
  LDAP_DEFAULTS.port = '';
  LDAP_DEFAULTS.searchResultsProfileMap = [
    {
      resultKey: 'cn',
      profileProperty: 'name'
    }
    ,{
      resultKey: 'mail',
      profileProperty: 'phoneNumber'
    }
  ]
});

Dear benco,

Thanks for giving so much important info.
Please help with these small questions

  1. I am creating a app on my local machine. so do not have any LDAP server.
    Can I use OpenLDAP server for this ?

  2. LDAP_DEFAULTS.url = ā€˜ldap://ā€™; ā€“ This is where I have to put server name
    am I correct ?

  3. I never worked on LDAP before can you provide me link to any documents ā€¦ I will be really gratefull

Thanks a lot sir

Hi Sandeep,

A1 - I believe so. My guess is that you will probably need to configure a local OpenLDAP server for your development purposes.

A2 - Yes. Just refer to the readme https://atmospherejs.com/typ/accounts-ldap. He does a good job describing with examples. Even includes LDAPS (LDAP + SSL) functionality now, which is really good if you need it.

A3 - I had never worked with LDAP before either and usually consider it an IT/config oriented thing. Thereā€™s info out there. Try http://ldapjs.org/guide.html. I never found a treasure trove of ā€œAll Things LDAPā€ unfortunately, so I suggest Googling and building a basic conceptual understanding that way. As mentioned previously, for package specific questions, Eric is pretty good about responding. Good luck!

Hello benco

I am grateful for all the help you providedā€¦I am close to a working solution but now facing this error, Could you please have a look

I am getting this output

1.User found in LDAP but not in application

2.LDAP Authentication succeeded for mike, but no user exists in Meteor. Either create the user manually or set LDAP_DEFAULTS.createNewUser to true

When I set
LDAP_DEFAULTS.createNewUser = true

Application is crashing with error
Exception while invoking method ā€˜loginā€™ TypeError: Object [object Object] has no method 'createUser

Please help me achieve a solution

Code is :-

Client end -
ā€˜click #login-btnā€™(event, instance) {
event.preventDefault();
var username = $("#login-form-username").val();
var password = $("#login-form-password").val();

     Meteor.loginWithLDAP(username, password,
       { dn: "uid=" + username + ",ou=people,dc=tup,dc=com" },
       function (error, success) {
         if (error) {
            console.log(error.reason);
         } else {
            console.log("Hip Hip Hurray");
        };
   });

}

Server end:-

Meteor.startup(() => {
LDAP_DEFAULTS.url = ā€˜ldap://localhostā€™;
LDAP_DEFAULTS.dn = ā€˜ou=people,dc=tup,dc=comā€™;
LDAP_DEFAULTS.port = ā€˜389ā€™;
LDAP_DEFAULTS.createNewUser = false;
});

Also how to ask typ90 - author of package for help

Hi Benco -

included accounts-password package and new user got created in Meteor.users() Collection.
So LDAP Authentication is achieved . Problem solved :smile:

Thanks for all the help and guidance you give me .

One more query

New document in Meteor.users only contain username ā€” how to insert a profile (email, age etc) when new user created If any idea


Also How to login through email ID instead of username
when I know dn
because when I do

searchBeforeBind: {
mail: email
}

error : Exception while invoking method ā€˜loginā€™ TypeError: Object false has no method ā€˜mapā€™

Appreciate any help

Thanks again

Insert new profile

Thisis how I did that back when i was testing it:

LDAP_DEFAULTS.searchResultsProfileMap = [{
  resultKey: 'mail',
  profileProperty: 'wemail'
        }, {
  resultKey: 'name',
  profileProperty: 'name'
        }, {
  resultKey: 'employeeNumber',
  profileProperty: 'EID'
        }];

Login Through Email ID

To authenticdate with email I had to custom change the search field.

LDAP_DEFAULTS.search = '(&(objectClass=person)(email={{username}}))'

And then right before calling Meteor.LoginWithLDAP(...); I did:

LDAP_DEFAULTS.search = LDAP_DEFAULTS.search.replace("{{username}}",loginSelector);
1 Like

I am getting this error when i am using this LDAP library
events.js:141
W20170316-11:19:18.295(-5)? (STDERR) throw er; // Unhandled ā€˜errorā€™ event
W20170316-11:19:18.296(-5)? (STDERR) ^
W20170316-11:19:18.297(-5)? (STDERR) SizeLimitExceededError: Size Limit Exceeded
W20170316-11:19:18.299(-5)? (STDERR) at messageCallback (C:\Users\sravu\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:867:40)
W20170316-11:19:18.301(-5)? (STDERR) at Parser.onMessage (C:\Users\sravu\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:199:12)
W20170316-11:19:18.303(-5)? (STDERR) at emitOne (events.js:77:13)
W20170316-11:19:18.303(-5)? (STDERR) at Parser.emit (events.js:169:7)
W20170316-11:19:18.304(-5)? (STDERR) at Parser.write (C:\Users\sravu\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\messages\parser.js:105:8)
W20170316-11:19:18.305(-5)? (STDERR) at end (C:\Users\sravu\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\messages\parser.js:71:19)
W20170316-11:19:18.305(-5)? (STDERR) at Parser.write (C:\Users\sravu\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\messages\parser.js:107:10)
W20170316-11:19:18.306(-5)? (STDERR) at Socket.onData (C:\Users\sravu\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:155:24)
W20170316-11:19:18.307(-5)? (STDERR) at emitOne (events.js:77:13)
W20170316-11:19:18.307(-5)? (STDERR) at Socket.emit (events.js:169:7)

Iā€™m hoping someone can help with my issues. Again I am a less that novice user of LDAP and Iā€™m trying to authenticate users on an app against my companyā€™s corporate Active Directory. But running in to a couple of issues:

My LDAP_Defaults looks like:

{ url: 'ldap://XXX.XXX.XXX.XXX',
  port: '389',
  dn: 'DC=XXX,DC=com',
  searchDN: 'CN=XXX,OU=XXX,OU=XXX,DC=XXX,DC=com',
  searchCredentials: 'XXXX',
  createNewUser: true,
  defaultDomain: false,
  searchResultsProfileMap: 
   [ { resultKey: 'givenName', profileProperty: 'name' },
     { resultKey: 'sn', profileProperty: 'surname' },
     { resultKey: 'sAMAccountName', profileProperty: 'username' },
     { resultKey: 'memberOf', profileProperty: 'memberOf' },
     { resultKey: 'email', profileProperty: 'email' } ],
  base: 'CN=XXX,OU=ES-ResourceAccess,OU=XXX,OU=XXX,DC=XXX,DC=com',
  search: '(objectclass=*)',
  ldapsCertificate: false }

And with this I get a ā€œFuture resolved more than onceā€ error:

C:\Users\cro32\AppData\Local.meteor\packages\meteor-tool\1.4.3_2\mt-os.windows.x86_32\dev_bundle\server-lib\node_modules\fibers\future.js:261
throw new Error(ā€˜Future resolved more than onceā€™);
^

Error: Future resolved more than once
at Object.Future.return (C:\Users\cro32\AppData\Local.meteor\packages\meteor-tool\1.4.3_2\mt-os.windows.x86_32\dev_bundle\server-lib\node_modules\fibers\future.js:261:10)
at packages\typ_accounts-ldap.js:171:64
at _done (C:\Users\cro32\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:789:14)
at messageCallback (C:\Users\cro32\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:867:18)
at Parser.onMessage (C:\Users\cro32\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:199:12)
at emitOne (events.js:77:13)
at Parser.emit (events.js:169:7)
at Parser.write (C:\Users\cro32\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\messages\parser.js:105:8)
at Socket.onData (C:\Users\cro32\AppData\Local.meteor\packages\typ_ldapjs\0.7.3\npm\node_modules\ldapjs\lib\client\client.js:155:24)
at emitOne (events.js:77:13)
Exited with code: 1
Your application is crashing. Waiting for file change.

I get a user entry in the MongoDB with this (but the error crashes the app) and it doesnt look right.

If I fiddle with the searchDn, base and DN fields I can get Authentication errors in the client console (firefox) or (STDERR) SizeLimitExceededError: Size Limit Exceeded

I think what will really help is undertanding what LDAP_Defaults.dn, LDAP_Defaults.searchDN & LDAP_Defaults.base are doing.

Then I MIGHT be able to work out it, but frankly Im completley lost now.