Skip to content
This repository

Allow LDAP BindAuthenticator to skip attribute retrieval or retrieve using manager context #9

Closed
wants to merge 1 commit into from

2 participants

Adam Lewandowski Rob Winch
Adam Lewandowski

This patch adds a couple of properties (retrieveUserAttributes and retrieveAttributesWithManagerContext) that provide more control over how BindAuthenticator retrieves user attributes. If retrieveUserAttributes is set to false no user attributes will be retrieved and if retrieveAttributesWithManagerContext is set to true, the attributes are retrieved with the manager context (contextSource property) as opposed to the context obtained from the user bind.
I have seen SEC-1510 , and humbly ask that the 'Won't Fix' resolution be reconsidered. I have run in to multiple LDAP server configurations that throw errors when users attempt to access their own attributes, rendering the BindAuthenticator unusable even if you aren't interested in those attribute values at all. The suggested workaround on the jira issue (reimplement AuthenticationProvider) seems heavy-handed, throwing away the baby with the bathwater. I can understand the desire to keep the complexity down, but the way this patch is implemented preserves the default functionality (get user attribs, using the user context). Only someone who wanted to would need to set the additional properties. I think this situation is common enough in security-conscious enterprises that BindAuthenticator should at least allow configuration to prevent it from retrieving user attributes at all.

Adam Lewandowski Add properties to BindAuthenticator allowing it to bypass user attrib…
…ute retrieval or retrieve the attributes using the manager context (instead of the user context). Existing behavior (retrieve attributes, using user context) is preserved as default.
dcd4aed
Rob Winch
Collaborator

As @tekul mentioned on SEC-1510 adding additional complexity to the existing classes is not desirable. The reason is that LDAP has too many permutations to support all scenarios (especially in a single class). Instead, you are encouraged to extend AbstractLdapAuthenticator and implement this yourself. For this reason this will be closed without being merged.

Rob Winch rwinch closed this March 18, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Jun 08, 2012
Adam Lewandowski Add properties to BindAuthenticator allowing it to bypass user attrib…
…ute retrieval or retrieve the attributes using the manager context (instead of the user context). Existing behavior (retrieve attributes, using user context) is preserved as default.
dcd4aed
This page is out of date. Refresh to see the latest.
16  ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java
@@ -127,4 +127,20 @@ public void testUserDnPatternReturnsCorrectDn() {
127 127
         authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"});
128 128
         assertEquals("cn=Joe,ou=people", authenticator.getUserDns("Joe").get(0));
129 129
     }
  130
+    
  131
+    @Test
  132
+    public void testRetrieveUserAttributes() {    	  
  133
+        authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people", "cn={0},ou=people"});        
  134
+        DirContextOperations user = authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword"));
  135
+        assertEquals("Mouse", user.getStringAttribute("sn"));        
  136
+    }
  137
+
  138
+    @Test
  139
+    public void testDoNotRetrieveUserAttributes() {    	  
  140
+        authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people", "cn={0},ou=people"});        
  141
+        authenticator.setRetrieveUserAttributes(false);
  142
+        DirContextOperations user = authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword"));
  143
+        assertNull(user.getStringAttribute("sn"));        
  144
+    }
  145
+    
130 146
 }
58  ldap/src/main/java/org/springframework/security/ldap/authentication/BindAuthenticator.java
@@ -36,7 +36,8 @@
36 36
 
37 37
 
38 38
 /**
39  
- * An authenticator which binds as a user.
  39
+ * An authenticator which binds as a user, optionally retrieving user
  40
+ * attributes.
40 41
  *
41 42
  * @author Luke Taylor
42 43
  *
@@ -47,6 +48,10 @@
47 48
 
48 49
     private static final Log logger = LogFactory.getLog(BindAuthenticator.class);
49 50
 
  51
+    //~ Instance fields =====================================================================================
  52
+     private boolean retrieveUserAttributes = true;
  53
+     private boolean retrieveAttributesWithManagerContext = false;
  54
+
50 55
     //~ Constructors ===================================================================================================
51 56
 
52 57
     /**
@@ -113,9 +118,7 @@ private DirContextOperations bindWithDn(String userDnStr, String username, Strin
113 118
             // Check for password policy control
114 119
             PasswordPolicyControl ppolicy = PasswordPolicyControlExtractor.extractControl(ctx);
115 120
 
116  
-            logger.debug("Retrieving attributes...");
117  
-
118  
-            Attributes attrs = ctx.getAttributes(userDn, getUserAttributes());
  121
+            Attributes attrs = retrieveUserAttribute(userDn, ctx);
119 122
 
120 123
             DirContextAdapter result = new DirContextAdapter(attrs, userDn, ctxSource.getBaseLdapPath());
121 124
 
@@ -142,6 +145,25 @@ private DirContextOperations bindWithDn(String userDnStr, String username, Strin
142 145
 
143 146
         return null;
144 147
     }
  148
+   
  149
+    /**
  150
+     * Retrieves user attributes, using either the user's bind context or the manager context.
  151
+     */
  152
+    protected Attributes retrieveUserAttribute(DistinguishedName userDn,DirContext userContext) throws javax.naming.NamingException {
  153
+        Attributes attrs = null;
  154
+        if (retrieveUserAttributes) {
  155
+            DirContext ctx = null;
  156
+            if (retrieveAttributesWithManagerContext) {
  157
+                logger.debug("Retrieving attributes using manager context...");
  158
+                ctx = getContextSource().getReadOnlyContext();
  159
+            } else {
  160
+                logger.debug("Retrieving attributes using user context...");
  161
+                ctx = userContext;
  162
+            }
  163
+            attrs = ctx.getAttributes(userDn, getUserAttributes());
  164
+        }
  165
+        return attrs;
  166
+    }
145 167
 
146 168
     /**
147 169
      * Allows subclasses to inspect the exception thrown by an attempt to bind with a particular DN.
@@ -152,4 +174,32 @@ protected void handleBindException(String userDn, String username, Throwable cau
152 174
             logger.debug("Failed to bind as " + userDn + ": " + cause);
153 175
         }
154 176
     }
  177
+
  178
+    public boolean isRetrieveUserAttributes() {
  179
+        return retrieveUserAttributes;
  180
+    }
  181
+
  182
+    /**
  183
+     * If set to false, no user attributes will be retrieved after binding as
  184
+     * the user. Default is true.
  185
+     */
  186
+    public void setRetrieveUserAttributes(boolean retrieveUserAttributes) {
  187
+        this.retrieveUserAttributes = retrieveUserAttributes;
  188
+    }
  189
+
  190
+    public boolean isRetrieveAttributesWithManagerContext() {
  191
+        return retrieveAttributesWithManagerContext;
  192
+    }
  193
+
  194
+    /**
  195
+     * If set to true (the default), user attributes are retrieved using the
  196
+     * {@link DirContextOperations} obtained when binding as the user. If set to
  197
+     * false, the manager context (the {@link ContextSource} supplied as
  198
+     * constructor argument) is used.
  199
+     */
  200
+    public void setRetrieveAttributesWithManagerContext(
  201
+        boolean retrieveAttributesWithManagerContext) {
  202
+        this.retrieveAttributesWithManagerContext = retrieveAttributesWithManagerContext;
  203
+    }
  204
+
155 205
 }
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.