auth0 / passport-windowsauth

Windows Authentication strategy for Passport.js
MIT License
179 stars 51 forks source link

Encrypting Network Comminucation to AD #22

Closed koalup closed 9 years ago

koalup commented 9 years ago

This module works really well, but I was curious if it were possible to encrypt network communication from the node server to active directory. I'm using non-integrated authentication and didn't see an option in the readme for configuring passport-windowsauth to talk to AD over ssl.

Thanks!

jfromaniello commented 9 years ago

Yes, this is possible:

passport.use(new WindowsStrategy({
  ldap: {
    url:             'ldaps://wellscordoba.wellscordobabank.com/DC=wellscordobabank,DC=com',

You need to use ldaps in the url. This is because ldap.js supports it:

http://ldapjs.org/client.html

koalup commented 9 years ago

Thank you. This is great. I switched the url to ldaps and got the following error:

LDAP connection error: [Error: CERT_UNTRUSTED] Error binding to LDAP dn: undefined code: undefined message: CERT_UNTRUSTED

I think this is because we use an internal CA. Is there a way to specify in the config the path to a root certificate for our internal CA?

Thank you!

jfromaniello commented 9 years ago

Yes, I think you will have to pass your ca root in tlsOptions.ca:

https://github.com/mcavage/node-ldapjs/blob/master/lib/client/client.js#L942 http://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback

not sure

koalup commented 9 years ago

Thank you for all your help so far. I looked at the code where you make calls to ldap.createClient and found that tlsOptions wasn't being passed in:

https://github.com/auth0/passport-windowsauth/blob/master/lib/LdapLookup.js#L14 https://github.com/auth0/passport-windowsauth/blob/master/lib/LdapValidator.js#L24

So I experimented with your code and put the following in LdapLookup.js:

this._client = ldap.createClient({ url: options.url, maxConnections: 10, bindDN: options.bindDN, credentials: options.bindCredentials, tlsOptions: options.tlsOptions });

and in LdapValidator.js:

var client = ldap.createClient({ url: this._options.url, tlsOptions: this._options.tlsOptions });

Then I tried the following options in my config:

    ldap: {
        url             : 'ldaps://host.domain.net/DC=domain,DC=net',
        base            : 'DC=domain,DC=net',
        bindDN          : 'USER@DOMAIN.NET',
        bindCredentials : 'password',
        tlsOptions: {
            rejectUnauthorized: false
        }
    }

and it worked!. I haven't quite figured out what certificates I should use so that's why I didn't pass in the ca variable, but, from what I understand, rejectUnauthorized ignores certificate errors. As a test, I changed rejectUnauthorized to true and got the CERT_UNTRUSTED error.

koalup commented 9 years ago

Just a quick update. I passed in the root CA to tlsOptions.ca and set tlsOptions.rejectUnauthorized to true and it works as well. Would it be possible to implement this functionality into the next release? Here's the config I used.

    ldap: {
        url             : 'ldaps://host.domain.net/DC=domain,DC=net',
        base            : 'DC=domain,DC=net',
        bindDN          : 'USER@DOMAIN.NET',
        bindCredentials : 'password',
        tlsOptions: {
            ca: [
                fs.readFileSync('./config/rca.pem')
            ],
            rejectUnauthorized: true
        }
    }

Thanks!

jfromaniello commented 9 years ago

Yes, sure!

jfromaniello commented 9 years ago

glad to hear that it worked

koalup commented 9 years ago

Hey, I just wanted to follow up regarding this issue. I created a pull request with the changes and was wondering if there's anything else that I need to do to get this change into the main branch.

Thanks!

futurechan commented 9 years ago

:+1: