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.