zeppelin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From prabhjyotsi...@apache.org
Subject zeppelin git commit: [ZEPPELIN-3539] Add jceks stored password support for LDAP
Date Fri, 15 Jun 2018 07:50:07 GMT
Repository: zeppelin
Updated Branches:
  refs/heads/branch-0.8 731d0be6b -> efa09aa8c


[ZEPPELIN-3539] Add jceks stored password support for LDAP

This is to add support for storing password in jceks for LDAP (realm).

If the hadoopSecurityCredentialPath path is present and not empty in the shiro.ini, then the
password is read from the keystore file and it need not be stored inside the shiro.ini file.

[Improvement | Feature]

* [x] - Add documentation

* [ZEPPELIN-3539](https://issues.apache.org/jira/browse/ZEPPELIN-3539)

Create a keystore file using the hadoop credential command line
```
hadoop credential create ldapRealm.systemPassword -provider jceks://file/user/zeppelin/conf/zeppelin.jceks
```
Change the following values in the Shiro.ini file, and uncomment the line:
```
ldapRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/conf/zeppelin.jceks
```

* Does the licenses files need update? N/A
* Is there breaking changes for older versions? N/A
* Does this needs documentation? N/A

Author: Prabhjyot Singh <prabhjyotsingh@gmail.com>

Closes #3018 from prabhjyotsingh/ZEPPELIN-3539 and squashes the following commits:

4dcbaabb4 [Prabhjyot Singh] zeppelin server should not start if invaild configuration is applied
228022db3 [Prabhjyot Singh] doc for hadoopSecurityCredentialPath
1428b3d1b [Prabhjyot Singh] [ZEPPELIN-3539] Add jceks stored password support for LDAP

Change-Id: Id50532a0b05de1572efd7fb5dc8a67777ca66fb8

# Conflicts:
#	zeppelin-server/src/main/java/org/apache/zeppelin/realm/ActiveDirectoryGroupRealm.java
#	zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/efa09aa8
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/efa09aa8
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/efa09aa8

Branch: refs/heads/branch-0.8
Commit: efa09aa8c8d3545667eec856412d6e5033caa55e
Parents: 731d0be
Author: Prabhjyot Singh <prabhjyotsingh@gmail.com>
Authored: Thu Jun 14 12:46:08 2018 +0530
Committer: Prabhjyot Singh <prabhjyotsingh@gmail.com>
Committed: Fri Jun 15 13:18:59 2018 +0530

----------------------------------------------------------------------
 docs/setup/security/shiro_authentication.md     |  11 +
 .../realm/ActiveDirectoryGroupRealm.java        |  36 +--
 .../org/apache/zeppelin/realm/LdapRealm.java    | 284 +++++++++++--------
 3 files changed, 186 insertions(+), 145 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/efa09aa8/docs/setup/security/shiro_authentication.md
----------------------------------------------------------------------
diff --git a/docs/setup/security/shiro_authentication.md b/docs/setup/security/shiro_authentication.md
index e1bf650..a9dd13e 100644
--- a/docs/setup/security/shiro_authentication.md
+++ b/docs/setup/security/shiro_authentication.md
@@ -185,6 +185,17 @@ securityManager.sessionManager = $sessionManager
 securityManager.realms = $ldapRealm
 ```
 
+Also instead of specifying systemPassword in clear text in `shiro.ini` administrator can
choose to specify the same in "hadoop credential". 
+Create a keystore file using the hadoop credential command line:
+``` 
+hadoop credential create ldapRealm.systemPassword -provider jceks://file/user/zeppelin/conf/zeppelin.jceks
+```
+
+Add the following line in the `shiro.ini` file:
+``` 
+ldapRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/conf/zeppelin.jceks
+```
+
 ### PAM
 [PAM](https://en.wikipedia.org/wiki/Pluggable_authentication_module) authentication support
allows the reuse of existing authentication
 moduls on the host where Zeppelin is running. On a typical system modules are configured
per service for example sshd, passwd, etc. under `/etc/pam.d/`. You can

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/efa09aa8/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ActiveDirectoryGroupRealm.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ActiveDirectoryGroupRealm.java
b/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ActiveDirectoryGroupRealm.java
index 4f3626c..54650a4 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ActiveDirectoryGroupRealm.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/realm/ActiveDirectoryGroupRealm.java
@@ -17,18 +17,14 @@
 package org.apache.zeppelin.realm;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.security.alias.CredentialProvider;
-import org.apache.hadoop.security.alias.CredentialProviderFactory;
+import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.authc.UsernamePasswordToken;
-import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authz.AuthorizationException;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
-import org.apache.shiro.realm.Realm;
 import org.apache.shiro.realm.ldap.AbstractLdapRealm;
 import org.apache.shiro.realm.ldap.DefaultLdapContextFactory;
 import org.apache.shiro.realm.ldap.LdapContextFactory;
@@ -37,6 +33,16 @@ import org.apache.shiro.subject.PrincipalCollection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
@@ -44,11 +50,10 @@ import javax.naming.directory.Attributes;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapContext;
-import java.util.*;
 
 
 /**
- * A {@link Realm} that authenticates with an active directory LDAP
+ * A {@link org.apache.shiro.realm.Realm} that authenticates with an active directory LDAP
  * server to determine the roles for a particular user.  This implementation
  * queries for the user's groups and then maps the group names to roles using the
  * {@link #groupRolesMap}.
@@ -61,7 +66,7 @@ public class ActiveDirectoryGroupRealm extends AbstractLdapRealm {
 
   private static final String ROLE_NAMES_DELIMETER = ",";
 
-  String KEYSTORE_PASS = "activeDirectoryRealm.systemPassword";
+  final String keystorePass = "activeDirectoryRealm.systemPassword";
   private String hadoopSecurityCredentialPath;
 
   public void setHadoopSecurityCredentialPath(String hadoopSecurityCredentialPath) {
@@ -147,20 +152,7 @@ public class ActiveDirectoryGroupRealm extends AbstractLdapRealm {
     if (StringUtils.isEmpty(this.hadoopSecurityCredentialPath)) {
       password = this.systemPassword;
     } else {
-      try {
-        Configuration configuration = new Configuration();
-        configuration.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH,
-          this.hadoopSecurityCredentialPath);
-        CredentialProvider provider =
-          CredentialProviderFactory.getProviders(configuration).get(0);
-        CredentialProvider.CredentialEntry credEntry = provider.getCredentialEntry(
-            KEYSTORE_PASS);
-        if (credEntry != null) {
-          password = new String(credEntry.getCredential());
-        }
-      } catch (Exception e) {
-
-      }
+      password = LdapRealm.getSystemPassword(hadoopSecurityCredentialPath, keystorePass);
     }
     return password;
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/efa09aa8/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java b/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java
index b41ac68..1cc60d6 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java
@@ -19,27 +19,6 @@
 
 package org.apache.zeppelin.realm;
 
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
-import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
-import org.apache.shiro.authz.AuthorizationInfo;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
-import org.apache.shiro.crypto.hash.DefaultHashService;
-import org.apache.shiro.crypto.hash.Hash;
-import org.apache.shiro.crypto.hash.HashRequest;
-import org.apache.shiro.crypto.hash.HashService;
-import org.apache.shiro.realm.ldap.JndiLdapRealm;
-import org.apache.shiro.realm.ldap.LdapContextFactory;
-import org.apache.shiro.realm.ldap.LdapUtils;
-import org.apache.shiro.session.Session;
-import org.apache.shiro.subject.MutablePrincipalCollection;
-import org.apache.shiro.subject.PrincipalCollection;
-import org.apache.shiro.util.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -66,65 +45,87 @@ import javax.naming.ldap.Control;
 import javax.naming.ldap.LdapContext;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.PagedResultsControl;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.alias.CredentialProvider;
+import org.apache.hadoop.security.alias.CredentialProviderFactory;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.ShiroException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.crypto.hash.DefaultHashService;
+import org.apache.shiro.crypto.hash.Hash;
+import org.apache.shiro.crypto.hash.HashRequest;
+import org.apache.shiro.crypto.hash.HashService;
+import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
+import org.apache.shiro.realm.ldap.JndiLdapRealm;
+import org.apache.shiro.realm.ldap.LdapContextFactory;
+import org.apache.shiro.realm.ldap.LdapUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.MutablePrincipalCollection;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
- * Implementation of {@link org.apache.shiro.realm.ldap.JndiLdapRealm} that also
- * returns each user's groups. This implementation is heavily based on
- * org.apache.isis.security.shiro.IsisLdapRealm.
- * 
+ * Implementation of {@link org.apache.shiro.realm.ldap.JndiLdapRealm} that also returns
each user's
+ * groups. This implementation is heavily based on org.apache.isis.security.shiro.IsisLdapRealm.
+ *
  * <p>This implementation saves looked up ldap groups in Shiro Session to make them
  * easy to be looked up outside of this object
- * 
- * <p>Sample config for <tt>shiro.ini</tt>:
- * 
- * <p>[main] 
- * ldapRealm = org.apache.zeppelin.realm.LdapRealm
- * ldapRealm.contextFactory.url = ldap://localhost:33389
- * ldapRealm.contextFactory.authenticationMechanism = simple
- * ldapRealm.contextFactory.systemUsername = uid=guest,ou=people,dc=hadoop,dc=
- * apache,dc=org
- * ldapRealm.contextFactory.systemPassword = S{ALIAS=ldcSystemPassword}
- * ldapRealm.userDnTemplate = uid={0},ou=people,dc=hadoop,dc=apache,dc=org
- * # Ability to set ldap paging Size if needed default is 100
- * ldapRealm.pagingSize = 200
- * ldapRealm.authorizationEnabled = true
- * ldapRealm.searchBase = dc=hadoop,dc=apache,dc=org
- * ldapRealm.userSearchBase = dc=hadoop,dc=apache,dc=org
- * ldapRealm.groupSearchBase = ou=groups,dc=hadoop,dc=apache,dc=org
- * ldapRealm.userObjectClass = person
- * ldapRealm.groupObjectClass = groupofnames
- * # Allow userSearchAttribute to be customized
- * ldapRealm.userSearchAttributeName = sAMAccountName
- * ldapRealm.memberAttribute = member
- * # force usernames returned from ldap to lowercase useful for AD
- * ldapRealm.userLowerCase = true 
- * # ability set searchScopes subtree (default), one, base
- * ldapRealm.userSearchScope = subtree;
- * ldapRealm.groupSearchScope = subtree;
- * ldapRealm.userSearchFilter = (&(objectclass=person)(sAMAccountName={0}))
- * ldapRealm.groupSearchFilter = (&(objectclass=groupofnames)(member={0}))
- * ldapRealm.memberAttributeValueTemplate=cn={0},ou=people,dc=hadoop,dc=apache,
- * dc=org
- * # enable support for nested groups using the LDAP_MATCHING_RULE_IN_CHAIN operator
- * ldapRealm.groupSearchEnableMatchingRuleInChain = true
  *
- * <p># optional mapping from physical groups to logical application roles
- * ldapRealm.rolesByGroup = \ LDN_USERS: user_role,\ NYK_USERS: user_role,\
- * HKG_USERS: user_role,\ GLOBAL_ADMIN: admin_role,\ DEMOS: self-install_role
+ * <p>Sample config for <tt>shiro.ini</tt>:
  *
- * <p># optional list of roles that are allowed to authenticate
- * ldapRealm.allowedRolesForAuthentication = admin_role,user_role
- * 
- * <p>ldapRealm.permissionsByRole=\ user_role = *:ToDoItemsJdo:*:*,\
- * *:ToDoItem:*:*; \ self-install_role = *:ToDoItemsFixturesService:install:* ;
- * \ admin_role = *
- * 
- * <p>[urls]
- * **=authcBasic
- * 
- * <p>securityManager.realms = $ldapRealm
- * 
+ * <p>
+ *   [main]
+ *   ldapRealm = org.apache.zeppelin.realm.LdapRealm
+ *   ldapRealm.contextFactory.url = ldap://localhost:33389
+ *   ldapRealm.contextFactory.authenticationMechanism = simple
+ *   ldapRealm.contextFactory.systemUsername = uid=guest,ou=people,dc=hadoop,dc= apache,dc=org
+ *   ldapRealm.contextFactory.systemPassword = S{ALIAS=ldcSystemPassword}
+ *   ldapRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/zeppelin.jceks
+ *   ldapRealm.userDnTemplate = uid={0},ou=people,dc=hadoop,dc=apache,dc=org
+ *   # Ability to set ldap paging Size if needed default is 100
+ *   ldapRealm.pagingSize = 200
+ *   ldapRealm.authorizationEnabled = true
+ *   ldapRealm.searchBase = dc=hadoop,dc=apache,dc=org
+ *   ldapRealm.userSearchBase = dc=hadoop,dc=apache,dc=org
+ *   ldapRealm.groupSearchBase = ou=groups,dc=hadoop,dc=apache,dc=org
+ *   ldapRealm.userObjectClass = person
+ *   ldapRealm.groupObjectClass = groupofnames
+ *   # Allow userSearchAttribute to be customized
+ *   ldapRealm.userSearchAttributeName = sAMAccountName
+ *   ldapRealm.memberAttribute = member
+ *   # force usernames returned from ldap to lowercase useful for AD
+ *   ldapRealm.userLowerCase = true
+ *   # ability set searchScopes subtree (default), one, base
+ *   ldapRealm.userSearchScope = subtree;
+ *   ldapRealm.groupSearchScope = subtree;
+ *   ldapRealm.userSearchFilter = (&(objectclass=person)(sAMAccountName={0}))
+ *   ldapRealm.groupSearchFilter = (&(objectclass=groupofnames)(member={0}))
+ *   ldapRealm.memberAttributeValueTemplate=cn={0},ou=people,dc=hadoop,dc=apache,dc=org
+ *   # enable support for nested groups using the LDAP_MATCHING_RULE_IN_CHAIN operator
+ *   ldapRealm.groupSearchEnableMatchingRuleInChain = true
+ * <p>
+ *   # optional mapping from physical groups to logical application roles
+ *   ldapRealm.rolesByGroup = \ LDN_USERS: user_role,\ NYK_USERS: user_role,\ HKG_USERS:
user_role,
+ *   \GLOBAL_ADMIN: admin_role,\ DEMOS: self-install_role
+ * <p>
+ *   # optional list of roles that are allowed to authenticate
+ *   ldapRealm.allowedRolesForAuthentication = admin_role,user_role
+ * <p>
+ *   ldapRealm.permissionsByRole=\ user_role = *:ToDoItemsJdo:*:*,\*:ToDoItem:*:*;
+ *   \ self-install_role = *:ToDoItemsFixturesService:install:* ; \ admin_role = *
+ * <p>
+ *   [urls]
+ *   **=authcBasic
+ * <p>
+ *   securityManager.realms = $ldapRealm
  */
 public class LdapRealm extends JndiLdapRealm {
 
@@ -135,11 +136,11 @@ public class LdapRealm extends JndiLdapRealm {
   private static final String SUBJECT_USER_GROUPS = "subject.userGroups";
   private static final String MEMBER_URL = "memberUrl";
   private static final String POSIX_GROUP = "posixGroup";
-  
+
   // LDAP Operator '1.2.840.113556.1.4.1941'
   // walks the chain of ancestry in objects all the way to the root until it finds a match
   // see https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx
-  private static final String MATCHING_RULE_IN_CHAIN_FORMAT = 
+  private static final String MATCHING_RULE_IN_CHAIN_FORMAT =
       "(&(objectClass=%s)(%s:1.2.840.113556.1.4.1941:=%s))";
 
   private static Pattern TEMPLATE_PATTERN = Pattern.compile("\\{(\\d+?)\\}");
@@ -187,6 +188,9 @@ public class LdapRealm extends JndiLdapRealm {
   private final Map<String, List<String>> permissionsByRole = 
       new LinkedHashMap<String, List<String>>();
 
+  private String hadoopSecurityCredentialPath;
+  final String keystorePass = "ldapRealm.systemPassword";
+
   private boolean authorizationEnabled;
 
   private String userSearchAttributeName;
@@ -194,6 +198,12 @@ public class LdapRealm extends JndiLdapRealm {
 
   private HashService hashService = new DefaultHashService();
 
+
+
+  public void setHadoopSecurityCredentialPath(String hadoopSecurityCredentialPath) {
+    this.hadoopSecurityCredentialPath = hadoopSecurityCredentialPath;
+  }
+
   public LdapRealm() {
     HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(HASHING_ALGORITHM);
     setCredentialsMatcher(credentialsMatcher);
@@ -210,6 +220,37 @@ public class LdapRealm extends JndiLdapRealm {
     }
   }
 
+  protected void onInit() {
+    super.onInit();
+    if (!org.apache.commons.lang.StringUtils.isEmpty(this.hadoopSecurityCredentialPath)
+        && getContextFactory() != null) {
+      ((JndiLdapContextFactory) getContextFactory()).setSystemPassword(
+          getSystemPassword(this.hadoopSecurityCredentialPath, keystorePass));
+    }
+  }
+
+  static String getSystemPassword(String hadoopSecurityCredentialPath,
+      String keystorePass) {
+    String password = "";
+    try {
+      Configuration configuration = new Configuration();
+      configuration.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH,
+          hadoopSecurityCredentialPath);
+      CredentialProvider provider = CredentialProviderFactory.getProviders(configuration).get(0);
+      CredentialProvider.CredentialEntry credEntry = provider.getCredentialEntry(keystorePass);
+      if (credEntry != null) {
+        password = new String(credEntry.getCredential());
+      }
+    } catch (IOException e) {
+      throw new ShiroException("Error from getting credential entry from keystore", e);
+    }
+    if (org.apache.commons.lang.StringUtils.isEmpty(password)) {
+      throw new ShiroException("Error getting SystemPassword from the provided keystore:"
+          + keystorePass + ", in path:" + hadoopSecurityCredentialPath);
+    }
+    return password;
+  }
+
   /**
    * This overrides the implementation of queryForAuthenticationInfo inside JndiLdapRealm.
    * In addition to calling the super method for authentication it also tries to validate
@@ -223,8 +264,7 @@ public class LdapRealm extends JndiLdapRealm {
    */
   @Override
   protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token,
-                                                          LdapContextFactory ldapContextFactory)
-      throws NamingException {
+      LdapContextFactory ldapContextFactory) throws NamingException {
     AuthenticationInfo info = super.queryForAuthenticationInfo(token, ldapContextFactory);
     // Credentials were verified. Verify that the principal has all allowedRulesForAuthentication
     if (!hasAllowedAuthenticationRules(info.getPrincipals(), ldapContextFactory)) {
@@ -268,7 +308,7 @@ public class LdapRealm extends JndiLdapRealm {
     boolean allowed = allowedRolesForAuthentication.isEmpty();
     if (!allowed) {
       Set<String> roles = getRoles(principals, ldapContextFactory);
-      for (String allowedRole: allowedRolesForAuthentication) {
+      for (String allowedRole : allowedRolesForAuthentication) {
         if (roles.contains(allowedRole)) {
           log.debug("Allowed role for user [" + allowedRole + "] found.");
           allowed = true;
@@ -338,7 +378,7 @@ public class LdapRealm extends JndiLdapRealm {
                 String.format(
                     MATCHING_RULE_IN_CHAIN_FORMAT, groupObjectClass, memberAttribute, userDn),
                 searchControls);
-            while (searchResultEnum != null && searchResultEnum.hasMore()) { 
+            while (searchResultEnum != null && searchResultEnum.hasMore()) {
               // searchResults contains all the groups in search scope
               numResults++;
               final SearchResult group = searchResultEnum.next();
@@ -352,7 +392,7 @@ public class LdapRealm extends JndiLdapRealm {
               } else {
                 roleNames.add(groupName);
               }
-            }                
+            }
           } else {
             // Default group search filter
             String searchFilter = String.format("(objectclass=%1$s)", groupObjectClass);
@@ -370,7 +410,7 @@ public class LdapRealm extends JndiLdapRealm {
                 getGroupSearchBase(),
                 searchFilter,
                 searchControls);
-            while (searchResultEnum != null && searchResultEnum.hasMore()) { 
+            while (searchResultEnum != null && searchResultEnum.hasMore()) {
               // searchResults contains all the groups in search scope
               numResults++;
               final SearchResult group = searchResultEnum.next();
@@ -385,12 +425,12 @@ public class LdapRealm extends JndiLdapRealm {
           }
         }
         // Re-activate paged results
-        ldapCtx.setRequestControls(new Control[]{new PagedResultsControl(pageSize, 
-              cookie, Control.CRITICAL)});
+        ldapCtx.setRequestControls(new Control[]{new PagedResultsControl(pageSize,
+            cookie, Control.CRITICAL)});
       } while (cookie != null);
     } catch (SizeLimitExceededException e) {
-      log.info("Only retrieved first " + numResults + 
-            " groups due to SizeLimitExceededException.");
+      log.info("Only retrieved first " + numResults +
+          " groups due to SizeLimitExceededException.");
     } catch (IOException e) {
       log.error("Unabled to setup paged results");
     }
@@ -402,7 +442,7 @@ public class LdapRealm extends JndiLdapRealm {
       ((MutablePrincipalCollection) principals).addAll(groupNames, getName());
     }
     if (log.isDebugEnabled()) {
-      log.debug("User RoleNames: " + userName + "::" + roleNames);  
+      log.debug("User RoleNames: " + userName + "::" + roleNames);
     }
     return roleNames;
   }
@@ -418,9 +458,8 @@ public class LdapRealm extends JndiLdapRealm {
   }
 
   private void addRoleIfMember(final String userDn, final SearchResult group,
-        final Set<String> roleNames, final Set<String> groupNames, 
-        final LdapContextFactory ldapContextFactory) throws NamingException {
-
+      final Set<String> roleNames, final Set<String> groupNames,
+      final LdapContextFactory ldapContextFactory) throws NamingException {
     NamingEnumeration<? extends Attribute> attributeEnum = null;
     NamingEnumeration<?> ne = null;
     try {
@@ -439,7 +478,7 @@ public class LdapRealm extends JndiLdapRealm {
           String attrValue = ne.next().toString();
           if (memberAttribute.equalsIgnoreCase(MEMBER_URL)) {
             boolean dynamicGroupMember = isUserMemberOfDynamicGroup(userLdapDn, attrValue,
-                  ldapContextFactory);
+                ldapContextFactory);
             if (dynamicGroupMember) {
               groupNames.add(groupName);
               String roleName = roleNameFor(groupName);
@@ -487,7 +526,7 @@ public class LdapRealm extends JndiLdapRealm {
   public Map<String, String> getListRoles() {
     Map<String, String> groupToRoles = getRolesByGroup();
     Map<String, String> roles = new HashMap<>();
-    for (Map.Entry<String, String> entry : groupToRoles.entrySet()){
+    for (Map.Entry<String, String> entry : groupToRoles.entrySet()) {
       roles.put(entry.getValue(), entry.getKey());
     }
     return roles;
@@ -531,7 +570,7 @@ public class LdapRealm extends JndiLdapRealm {
   public int getPagingSize() {
     return pagingSize;
   }
-  
+
   public void setPagingSize(int pagingSize) {
     this.pagingSize = pagingSize;
   }
@@ -567,7 +606,7 @@ public class LdapRealm extends JndiLdapRealm {
   public void setGroupIdAttribute(String groupIdAttribute) {
     this.groupIdAttribute = groupIdAttribute;
   }
-  
+
   /**
   * Set Member Attribute Template for LDAP.
   * 
@@ -584,7 +623,7 @@ public class LdapRealm extends JndiLdapRealm {
     int index = template.indexOf(MEMBER_SUBSTITUTION_TOKEN);
     if (index < 0) {
       String msg = "Member attribute value template must contain the '" + MEMBER_SUBSTITUTION_TOKEN
-            + "' replacement token to understand how to " + "parse the group members.";
+          + "' replacement token to understand how to " + "parse the group members.";
       throw new IllegalArgumentException(msg);
     }
     String prefix = template.substring(0, index);
@@ -600,7 +639,7 @@ public class LdapRealm extends JndiLdapRealm {
   public void setRolesByGroup(Map<String, String> rolesByGroup) {
     this.rolesByGroup.putAll(rolesByGroup);
   }
-  
+
   public Map<String, String> getRolesByGroup() {
     return rolesByGroup;
   }
@@ -608,7 +647,7 @@ public class LdapRealm extends JndiLdapRealm {
   public void setPermissionsByRole(String permissionsByRoleStr) {
     permissionsByRole.putAll(parsePermissionByRoleString(permissionsByRoleStr));
   }
-  
+
   public Map<String, List<String>> getPermissionsByRole() {
     return permissionsByRole;
   }
@@ -624,7 +663,7 @@ public class LdapRealm extends JndiLdapRealm {
   public String getUserSearchAttributeName() {
     return userSearchAttributeName;
   }
-  
+
   /**
   * Set User Search Attribute Name for LDAP.
   * 
@@ -670,8 +709,7 @@ public class LdapRealm extends JndiLdapRealm {
   }
 
   boolean isUserMemberOfDynamicGroup(LdapName userLdapDn, String memberUrl,
-        final LdapContextFactory ldapContextFactory) throws NamingException {
-
+      final LdapContextFactory ldapContextFactory) throws NamingException {
     // ldap://host:port/dn?attributes?scope?filter?extensions
 
     if (memberUrl == null) {
@@ -708,7 +746,7 @@ public class LdapRealm extends JndiLdapRealm {
     NamingEnumeration<SearchResult> searchResultEnum = null;
     try {
       searchResultEnum = systemLdapCtx.search(userLdapDn, searchFilter,
-            searchScope.equalsIgnoreCase("sub") ? SUBTREE_SCOPE : ONELEVEL_SCOPE);
+          searchScope.equalsIgnoreCase("sub") ? SUBTREE_SCOPE : ONELEVEL_SCOPE);
       if (searchResultEnum.hasMore()) {
         return true;
       }
@@ -727,7 +765,7 @@ public class LdapRealm extends JndiLdapRealm {
   public String getPrincipalRegex() {
     return principalRegex;
   }
-  
+
   /**
   * Set Regex for Principal LDAP.
   * 
@@ -761,7 +799,7 @@ public class LdapRealm extends JndiLdapRealm {
   public void setUserSearchFilter(final String filter) {
     this.userSearchFilter = (filter == null ? null : filter.trim());
   }
-  
+
   public String getGroupSearchFilter() {
     return groupSearchFilter;
   }
@@ -773,11 +811,11 @@ public class LdapRealm extends JndiLdapRealm {
   public boolean getUserLowerCase() {
     return userLowerCase;
   }
-  
+
   public void setUserLowerCase(boolean userLowerCase) {
     this.userLowerCase = userLowerCase;
   }
-  
+
   public String getUserSearchScope() {
     return userSearchScope;
   }
@@ -793,7 +831,7 @@ public class LdapRealm extends JndiLdapRealm {
   public void setGroupSearchScope(final String scope) {
     this.groupSearchScope = (scope == null ? null : scope.trim().toLowerCase());
   }
-  
+
   public boolean isGroupSearchEnableMatchingRuleInChain() {
     return groupSearchEnableMatchingRuleInChain;
   }
@@ -812,7 +850,7 @@ public class LdapRealm extends JndiLdapRealm {
     }
     return searchControls;
   }
-  
+
   protected SearchControls getGroupSearchControls() {
     SearchControls searchControls = SUBTREE_SCOPE;
     if ("onelevel".equalsIgnoreCase(groupSearchScope)) {
@@ -831,8 +869,8 @@ public class LdapRealm extends JndiLdapRealm {
   private String matchPrincipal(final String principal) {
     Matcher matchedPrincipal = principalPattern.matcher(principal);
     if (!matchedPrincipal.matches()) {
-      throw new IllegalArgumentException("Principal " 
-            + principal + " does not match " + principalRegex);
+      throw new IllegalArgumentException("Principal "
+          + principal + " does not match " + principalRegex);
     }
     return matchedPrincipal.group();
   }
@@ -862,8 +900,8 @@ public class LdapRealm extends JndiLdapRealm {
   * @see LdapContextFactory#getLdapContext(Object, Object)
   */
   @Override
-  protected String getUserDn(final String principal) throws IllegalArgumentException, 
-        IllegalStateException {
+  protected String getUserDn(final String principal) throws IllegalArgumentException,
+      IllegalStateException {
     String userDn;
     String matchedPrincipal = matchPrincipal(principal);
     String userSearchBase = getUserSearchBase();
@@ -871,7 +909,7 @@ public class LdapRealm extends JndiLdapRealm {
 
     // If not searching use the userDnTemplate and return.
     if ((userSearchBase == null || userSearchBase.isEmpty()) || (userSearchAttributeName
== null
-          && userSearchFilter == null && !"object".equalsIgnoreCase(userSearchScope)))
{
+        && userSearchFilter == null && !"object".equalsIgnoreCase(userSearchScope)))
{
       userDn = expandTemplate(userDnTemplate, matchedPrincipal);
       if (log.isDebugEnabled()) {
         log.debug("LDAP UserDN and Principal: " + userDn + "," + principal);
@@ -887,8 +925,8 @@ public class LdapRealm extends JndiLdapRealm {
         searchFilter = String.format("(objectclass=%1$s)", getUserObjectClass());
       } else {
         searchFilter = String.format("(&(objectclass=%1$s)(%2$s=%3$s))", getUserObjectClass(),
-              userSearchAttributeName, expandTemplate(getUserSearchAttributeTemplate(), 
-              matchedPrincipal));
+            userSearchAttributeName, expandTemplate(getUserSearchAttributeTemplate(),
+                matchedPrincipal));
       }
     } else {
       searchFilter = expandTemplate(userSearchFilter, matchedPrincipal);
@@ -901,8 +939,8 @@ public class LdapRealm extends JndiLdapRealm {
     try {
       systemLdapCtx = getContextFactory().getSystemLdapContext();
       if (log.isDebugEnabled()) {
-        log.debug("SearchBase,SearchFilter,UserSearchScope: " + searchBase 
-              + "," + searchFilter + "," + userSearchScope);
+        log.debug("SearchBase,SearchFilter,UserSearchScope: " + searchBase
+            + "," + searchFilter + "," + userSearchScope);
       }
       searchResultEnum = systemLdapCtx.search(searchBase, searchFilter, searchControls);
       // SearchResults contains all the entries in search scope
@@ -935,16 +973,16 @@ public class LdapRealm extends JndiLdapRealm {
   }
 
   @Override
-  protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token, 
-        Object ldapPrincipal,
-        Object ldapCredentials, LdapContext ldapContext) throws NamingException {
+  protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token,
+      Object ldapPrincipal, Object ldapCredentials, LdapContext ldapContext)
+      throws NamingException {
     HashRequest.Builder builder = new HashRequest.Builder();
     Hash credentialsHash = hashService
-          .computeHash(builder.setSource(token.getCredentials())
-                .setAlgorithmName(HASHING_ALGORITHM).build());
-    return new SimpleAuthenticationInfo(token.getPrincipal(), 
-          credentialsHash.toHex(), credentialsHash.getSalt(),
-          getName());
+        .computeHash(builder.setSource(token.getCredentials())
+            .setAlgorithmName(HASHING_ALGORITHM).build());
+    return new SimpleAuthenticationInfo(token.getPrincipal(),
+        credentialsHash.toHex(), credentialsHash.getSalt(),
+        getName());
   }
 
   protected static final String expandTemplate(final String template, final String input)
{


Mime
View raw message