diff --git a/ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java b/ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java index 69a1ac0f104..54e601b881a 100644 --- a/ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java +++ b/ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java @@ -127,4 +127,20 @@ public void testUserDnPatternReturnsCorrectDn() { authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); assertEquals("cn=Joe,ou=people", authenticator.getUserDns("Joe").get(0)); } + + @Test + public void testRetrieveUserAttributes() { + authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people", "cn={0},ou=people"}); + DirContextOperations user = authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword")); + assertEquals("Mouse", user.getStringAttribute("sn")); + } + + @Test + public void testDoNotRetrieveUserAttributes() { + authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people", "cn={0},ou=people"}); + authenticator.setRetrieveUserAttributes(false); + DirContextOperations user = authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword")); + assertNull(user.getStringAttribute("sn")); + } + } diff --git a/ldap/src/main/java/org/springframework/security/ldap/authentication/BindAuthenticator.java b/ldap/src/main/java/org/springframework/security/ldap/authentication/BindAuthenticator.java index 9ab1c7933b8..5893a8b9c88 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/authentication/BindAuthenticator.java +++ b/ldap/src/main/java/org/springframework/security/ldap/authentication/BindAuthenticator.java @@ -36,7 +36,8 @@ /** - * An authenticator which binds as a user. + * An authenticator which binds as a user, optionally retrieving user + * attributes. * * @author Luke Taylor * @@ -47,6 +48,10 @@ public class BindAuthenticator extends AbstractLdapAuthenticator { private static final Log logger = LogFactory.getLog(BindAuthenticator.class); + //~ Instance fields ===================================================================================== + private boolean retrieveUserAttributes = true; + private boolean retrieveAttributesWithManagerContext = false; + //~ Constructors =================================================================================================== /** @@ -113,9 +118,7 @@ private DirContextOperations bindWithDn(String userDnStr, String username, Strin // Check for password policy control PasswordPolicyControl ppolicy = PasswordPolicyControlExtractor.extractControl(ctx); - logger.debug("Retrieving attributes..."); - - Attributes attrs = ctx.getAttributes(userDn, getUserAttributes()); + Attributes attrs = retrieveUserAttribute(userDn, ctx); DirContextAdapter result = new DirContextAdapter(attrs, userDn, ctxSource.getBaseLdapPath()); @@ -142,6 +145,25 @@ private DirContextOperations bindWithDn(String userDnStr, String username, Strin return null; } + + /** + * Retrieves user attributes, using either the user's bind context or the manager context. + */ + protected Attributes retrieveUserAttribute(DistinguishedName userDn,DirContext userContext) throws javax.naming.NamingException { + Attributes attrs = null; + if (retrieveUserAttributes) { + DirContext ctx = null; + if (retrieveAttributesWithManagerContext) { + logger.debug("Retrieving attributes using manager context..."); + ctx = getContextSource().getReadOnlyContext(); + } else { + logger.debug("Retrieving attributes using user context..."); + ctx = userContext; + } + attrs = ctx.getAttributes(userDn, getUserAttributes()); + } + return attrs; + } /** * 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 logger.debug("Failed to bind as " + userDn + ": " + cause); } } + + public boolean isRetrieveUserAttributes() { + return retrieveUserAttributes; + } + + /** + * If set to false, no user attributes will be retrieved after binding as + * the user. Default is true. + */ + public void setRetrieveUserAttributes(boolean retrieveUserAttributes) { + this.retrieveUserAttributes = retrieveUserAttributes; + } + + public boolean isRetrieveAttributesWithManagerContext() { + return retrieveAttributesWithManagerContext; + } + + /** + * If set to true (the default), user attributes are retrieved using the + * {@link DirContextOperations} obtained when binding as the user. If set to + * false, the manager context (the {@link ContextSource} supplied as + * constructor argument) is used. + */ + public void setRetrieveAttributesWithManagerContext( + boolean retrieveAttributesWithManagerContext) { + this.retrieveAttributesWithManagerContext = retrieveAttributesWithManagerContext; + } + }