1 | # ldapauth-fork
|
2 |
|
3 | [![Sponsored by Wakeone](https://img.shields.io/badge/sponsored%20by-wakeone-389fc1.svg)](https://wakeone.co)
|
4 |
|
5 | Fork of [node-ldapauth](https://github.com/trentm/node-ldapauth) - A simple node.js lib to authenticate against an LDAP server.
|
6 |
|
7 | ## About the fork
|
8 |
|
9 | This fork was originally created and published because of an urgent need to get newer version of [ldapjs](http://ldapjs.org/) in use to [passport-ldapauth](https://github.com/vesse/passport-ldapauth) since the newer version supported passing `tlsOptions` to the TLS module. Since then a lot of issues from the original module ([#2](https://github.com/trentm/node-ldapauth/issues/2), [#3](https://github.com/trentm/node-ldapauth/issues/3), [#8](https://github.com/trentm/node-ldapauth/issues/8), [#10](https://github.com/trentm/node-ldapauth/issues/10), [#11](https://github.com/trentm/node-ldapauth/issues/11), [#12](https://github.com/trentm/node-ldapauth/issues/12), [#13](https://github.com/trentm/node-ldapauth/pull/13)) have been fixed, and new features have been added as well.
|
10 |
|
11 | Multiple [ldapjs](http://ldapjs.org/) client options have been made available.
|
12 |
|
13 | ## Usage
|
14 |
|
15 | ```javascript
|
16 | var LdapAuth = require('ldapauth-fork');
|
17 | var options = {
|
18 | url: 'ldaps://ldap.example.org:636',
|
19 | ...
|
20 | };
|
21 | var auth = new LdapAuth(options);
|
22 | auth.on('error', function (err) {
|
23 | console.error('LdapAuth: ', err);
|
24 | });
|
25 | ...
|
26 | auth.authenticate(username, password, function(err, user) { ... });
|
27 | ...
|
28 | auth.close(function(err) { ... })
|
29 | ```
|
30 |
|
31 | `LdapAuth` inherits from `EventEmitter`.
|
32 |
|
33 | ## Install
|
34 |
|
35 | npm install ldapauth-fork
|
36 |
|
37 | ## `LdapAuth` Config Options
|
38 |
|
39 | Required ldapjs client options:
|
40 |
|
41 | - `url` - LDAP server URL, eg. _ldaps://ldap.example.org:636_, or a list of URLs, e.g. `["ldaps://ldap.example.org:636"]`
|
42 |
|
43 | ldapauth-fork options:
|
44 |
|
45 | - `bindDN` - Admin connection DN, e.g. _uid=myapp,ou=users,dc=example,dc=org_. Optional. If not given at all, admin client is not bound. Giving empty string may result in anonymous bind when allowed.
|
46 | - `bindCredentials` - Password for bindDN.
|
47 | - `searchBase` - The base DN from which to search for users by username. E.g. _ou=users,dc=example,dc=org_
|
48 | - `searchFilter` - LDAP search filter with which to find a user by username, e.g. _(uid={{username}})_. Use the literal _{{username}}_ to have the given username interpolated in for the LDAP search.
|
49 | - `searchAttributes` - Optional, default all. Array of attributes to fetch from LDAP server.
|
50 | - `bindProperty` - Optional, default _dn_. Property of the LDAP user object to use when binding to verify the password. E.g. _name_, _email_
|
51 | - `searchScope` - Optional, default _sub_. Scope of the search, one of _base_, _one_, or _sub_.
|
52 |
|
53 | ldapauth-fork can look for valid users groups too. Related options:
|
54 |
|
55 | - `groupSearchBase` - Optional. The base DN from which to search for groups. If defined, also `groupSearchFilter` must be defined for the search to work.
|
56 | - `groupSearchFilter` - Optional. LDAP search filter for groups. Place literal _{{dn}}_ in the filter to have it replaced by the property defined with `groupDnProperty` of the found user object. _{{username}}_ is also available and will be replaced with the _uid_ of the found user. This is useful for example to filter PosixGroups by _memberUid_. Optionally you can also assign a function instead. The found user is passed to the function and it should return a valid search filter for the group search.
|
57 | - `groupSearchAttributes` - Optional, default all. Array of attributes to fetch from LDAP server.
|
58 | - `groupDnProperty` - Optional, default _dn_. The property of user object to use in _{{dn}}_ interpolation of `groupSearchFilter`.
|
59 | - `groupSearchScope` - Optional, default _sub_.
|
60 |
|
61 | Other ldapauth-fork options:
|
62 |
|
63 | - `includeRaw` - Optional, default false. Set to true to add property `_raw` containing the original buffers to the returned user object. Useful when you need to handle binary attributes
|
64 | - `cache` - Optional, default false. If true, then up to 100 credentials at a time will be cached for 5 minutes.
|
65 | - `log` - Bunyan logger instance, optional. If given this will result in TRACE-level error logging for component:ldapauth. The logger is also passed forward to ldapjs.
|
66 |
|
67 | Optional ldapjs options, see [ldapjs documentation](https://github.com/mcavage/node-ldapjs/blob/v1.0.1/docs/client.md):
|
68 |
|
69 | - `tlsOptions` - Needed for TLS connection. See [Node.js documentation](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
|
70 | - `socketPath`
|
71 | - `timeout`
|
72 | - `connectTimeout`
|
73 | - `idleTimeout`
|
74 | - `reconnect`
|
75 | - `strictDN`
|
76 | - `queueSize`
|
77 | - `queueTimeout`
|
78 | - `queueDisable`
|
79 |
|
80 | ## How it works
|
81 |
|
82 | The LDAP authentication flow is usually:
|
83 |
|
84 | 1. Bind the admin client using the given `bindDN` and `bindCredentials`
|
85 | 2. Use the admin client to search for the user by substituting `{{username}}` from the `searchFilter` with given username
|
86 | 3. If user is found, verify the given password by trying to bind the user client with the found LDAP user object and given password
|
87 | 4. If password was correct and group search options were provided, search for the groups of the user
|
88 |
|
89 | ## express/connect basicAuth example
|
90 |
|
91 | ```javascript
|
92 | var basicAuth = require('basic-auth');
|
93 | var LdapAuth = require('ldapauth-fork');
|
94 |
|
95 | var ldap = new LdapAuth({
|
96 | url: 'ldaps://ldap.example.org:636',
|
97 | bindDN: 'uid=myadminusername,ou=users,dc=example,dc=org',
|
98 | bindCredentials: 'mypassword',
|
99 | searchBase: 'ou=users,dc=example,dc=org',
|
100 | searchFilter: '(uid={{username}})',
|
101 | reconnect: true,
|
102 | });
|
103 |
|
104 | var rejectBasicAuth = function (res) {
|
105 | res.statusCode = 401;
|
106 | res.setHeader('WWW-Authenticate', 'Basic realm="Example"');
|
107 | res.end('Access denied');
|
108 | };
|
109 |
|
110 | var basicAuthMiddleware = function (req, res, next) {
|
111 | var credentials = basicAuth(req);
|
112 | if (!credentials) {
|
113 | return rejectBasicAuth(res);
|
114 | }
|
115 |
|
116 | ldap.authenticate(credentials.name, credentials.pass, function (err, user) {
|
117 | if (err) {
|
118 | return rejectBasicAuth(res);
|
119 | }
|
120 |
|
121 | req.user = user;
|
122 | next();
|
123 | });
|
124 | };
|
125 | ```
|
126 |
|
127 | ## License
|
128 |
|
129 | MIT
|
130 |
|
131 | `ldapauth-fork` has been partially sponsored by [Wakeone Ltd](https://wakeone.co/).
|