فهرست منبع

impl group search filter

Yuki Takei 8 سال پیش
والد
کامیت
924d23ce64
4فایلهای تغییر یافته به همراه38 افزوده شده و 7 حذف شده
  1. 3 1
      lib/form/admin/securityPassportLdap.js
  2. 3 0
      lib/models/config.js
  3. 15 0
      lib/routes/login-passport.js
  4. 17 6
      lib/service/passport.js

+ 3 - 1
lib/form/admin/securityPassportLdap.js

@@ -15,6 +15,8 @@ module.exports = form(
       .is(/^(,?[^,=\s]+=[^,=\s]+){1,}$/, 'Bind DN is invalid. <small><a href="https://regex101.com/r/jK8lpO/1">&gt;&gt; Regex</a></small>'),
       .is(/^(,?[^,=\s]+=[^,=\s]+){1,}$/, 'Bind DN is invalid. <small><a href="https://regex101.com/r/jK8lpO/1">&gt;&gt; Regex</a></small>'),
   field('settingForm[security:passport-ldap:bindDNPassword]'),
   field('settingForm[security:passport-ldap:bindDNPassword]'),
   field('settingForm[security:passport-ldap:searchFilter]'),
   field('settingForm[security:passport-ldap:searchFilter]'),
-  field('settingForm[security:passport-ldap:attrMapUsername]')
+  field('settingForm[security:passport-ldap:attrMapUsername]'),
+  field('settingForm[security:passport-ldap:groupSearchBase]'),
+  field('settingForm[security:passport-ldap:groupSearchFilter]')
 );
 );
 
 

+ 3 - 0
lib/models/config.js

@@ -61,6 +61,9 @@ module.exports = function(crowi) {
       'security:passport-ldap:bindDNPassword' : undefined,
       'security:passport-ldap:bindDNPassword' : undefined,
       'security:passport-ldap:searchFilter' : undefined,
       'security:passport-ldap:searchFilter' : undefined,
       'security:passport-ldap:attrMapUsername' : undefined,
       'security:passport-ldap:attrMapUsername' : undefined,
+      'security:passport-ldap:groupSearchBase' : undefined,
+      'security:passport-ldap:groupSearchFilter' : undefined,
+      'security:passport-ldap:groupDnProperty' : undefined,
 
 
       'aws:bucket'          : 'crowi',
       'aws:bucket'          : 'crowi',
       'aws:region'          : 'ap-northeast-1',
       'aws:region'          : 'ap-northeast-1',

+ 15 - 0
lib/routes/login-passport.js

@@ -79,6 +79,12 @@ module.exports = function(crowi, app) {
 
 
       // authentication failure
       // authentication failure
       if (!ldapAccountInfo) { return next(); }
       if (!ldapAccountInfo) { return next(); }
+      // check groups
+      if (ldapAccountInfo._groups != null) {
+        if (ldapAccountInfo._groups.length == 0) {
+          return loginFailure(req, res, next);
+        }
+      }
 
 
       /*
       /*
        * authentication success
        * authentication success
@@ -153,6 +159,15 @@ module.exports = function(crowi, app) {
         });
         });
       }
       }
       if (user) {
       if (user) {
+        // check groups
+        if (user._groups != null) {
+          if (user._groups.length == 0) {
+            return res.json({
+              status: 'warning',
+              message: 'An user is found, but the groups are empty.',
+            });
+          }
+        }
         return res.json({
         return res.json({
           status: 'success',
           status: 'success',
           message: 'Successfully authenticated.',
           message: 'Successfully authenticated.',

+ 17 - 6
lib/service/passport.js

@@ -156,11 +156,14 @@ class PassportService {
    */
    */
   getLdapConfigurationFunc(config, opts) {
   getLdapConfigurationFunc(config, opts) {
     // get configurations
     // get configurations
-    const isUserBind      = config.crowi['security:passport-ldap:isUserBind'];
-    const serverUrl       = config.crowi['security:passport-ldap:serverUrl'];
-    const bindDN          = config.crowi['security:passport-ldap:bindDN'];
-    const bindCredentials = config.crowi['security:passport-ldap:bindDNPassword'];
-    const searchFilter    = config.crowi['security:passport-ldap:searchFilter'] || '(uid={{username}})';
+    const isUserBind          = config.crowi['security:passport-ldap:isUserBind'];
+    const serverUrl           = config.crowi['security:passport-ldap:serverUrl'];
+    const bindDN              = config.crowi['security:passport-ldap:bindDN'];
+    const bindCredentials     = config.crowi['security:passport-ldap:bindDNPassword'];
+    const searchFilter        = config.crowi['security:passport-ldap:searchFilter'] || '(uid={{username}})';
+    const groupSearchBase     = config.crowi['security:passport-ldap:groupSearchBase'];
+    const groupSearchFilter   = config.crowi['security:passport-ldap:groupSearchFilter'];
+    const groupDnProperty     = config.crowi['security:passport-ldap:groupDnProperty'] || 'uid';
 
 
     // parse serverUrl
     // parse serverUrl
     // see: https://regex101.com/r/0tuYBB/1
     // see: https://regex101.com/r/0tuYBB/1
@@ -180,6 +183,9 @@ class PassportService {
       debug(`LdapStrategy: bindCredentials=${bindCredentials}`);
       debug(`LdapStrategy: bindCredentials=${bindCredentials}`);
     }
     }
     debug(`LdapStrategy: searchFilter=${searchFilter}`);
     debug(`LdapStrategy: searchFilter=${searchFilter}`);
+    debug(`LdapStrategy: groupSearchBase=${groupSearchBase}`);
+    debug(`LdapStrategy: groupSearchFilter=${groupSearchFilter}`);
+    debug(`LdapStrategy: groupDnProperty=${groupDnProperty}`);
 
 
     return (req, callback) => {
     return (req, callback) => {
       // get credentials from form data
       // get credentials from form data
@@ -193,12 +199,17 @@ class PassportService {
           bindDN.replace(/{{username}}/, loginForm.username):
           bindDN.replace(/{{username}}/, loginForm.username):
           bindDN;
           bindDN;
       const fixedBindCredentials = (isUserBind) ? loginForm.password : bindCredentials;
       const fixedBindCredentials = (isUserBind) ? loginForm.password : bindCredentials;
+      let serverOpt = { url, bindDN: fixedBindDN, bindCredentials: fixedBindCredentials, searchBase, searchFilter };
+
+      if (groupSearchBase && groupSearchFilter) {
+        serverOpt = Object.assign({ groupSearchBase, groupSearchFilter, groupDnProperty}, serverOpt);
+      }
 
 
       process.nextTick(() => {
       process.nextTick(() => {
         const mergedOpts = Object.assign({
         const mergedOpts = Object.assign({
           usernameField: PassportService.USERNAME_FIELD,
           usernameField: PassportService.USERNAME_FIELD,
           passwordField: PassportService.PASSWORD_FIELD,
           passwordField: PassportService.PASSWORD_FIELD,
-          server: { url, bindDN: fixedBindDN, bindCredentials: fixedBindCredentials, searchBase, searchFilter },
+          server: serverOpt,
         }, opts);
         }, opts);
         debug('ldap configuration: ', mergedOpts);
         debug('ldap configuration: ', mergedOpts);
         callback(null, mergedOpts);
         callback(null, mergedOpts);