Avoid duplicate attribute search.

When using search-and-bind strategy, the user attributes are already returned in the first search.
If the user happens to not have privileges to perform a search, the second search may fail.
(user only has bind privileges)
See https://github.com/cloudfoundry/uaa/issues/342
This commit is contained in:
Filip Hanik 2016-06-06 16:03:08 -06:00 committed by Rob Winch
parent ca76e8d784
commit 6b436ff409
2 changed files with 17 additions and 7 deletions

View File

@ -30,6 +30,7 @@ import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
* Tests for {@link BindAuthenticator}.
*
@ -90,7 +91,9 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests {
this.authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=people",
"(uid={0})", getContextSource()));
this.authenticator.afterPropertiesSet();
this.authenticator.authenticate(this.bob);
DirContextOperations result = this.authenticator.authenticate(this.bob);
//ensure we are getting the same attributes back
assertThat(result.getStringAttribute("cn")).isEqualTo("Bob Hamilton");
// SEC-1444
this.authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=people",
"(cn={0})", getContextSource()));

View File

@ -16,9 +16,6 @@
package org.springframework.security.ldap.authentication;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.NamingException;
@ -35,6 +32,9 @@ import org.springframework.security.ldap.ppolicy.PasswordPolicyControlExtractor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
/**
* An authenticator which binds as a user.
*
@ -93,7 +93,8 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
// with the returned DN.
if (user == null && getUserSearch() != null) {
DirContextOperations userFromSearch = getUserSearch().searchForUser(username);
user = bindWithDn(userFromSearch.getDn().toString(), username, password);
user = bindWithDn(userFromSearch.getDn().toString(), username, password,
userFromSearch.getAttributes());
}
if (user == null) {
@ -106,6 +107,11 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
private DirContextOperations bindWithDn(String userDnStr, String username,
String password) {
return bindWithDn(userDnStr, username, password, null);
}
private DirContextOperations bindWithDn(String userDnStr, String username,
String password, Attributes attrs) {
BaseLdapPathContextSource ctxSource = (BaseLdapPathContextSource) getContextSource();
DistinguishedName userDn = new DistinguishedName(userDnStr);
DistinguishedName fullDn = new DistinguishedName(userDn);
@ -121,8 +127,9 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
.extractControl(ctx);
logger.debug("Retrieving attributes...");
Attributes attrs = ctx.getAttributes(userDn, getUserAttributes());
if (attrs == null || attrs.size()==0) {
attrs = ctx.getAttributes(userDn, getUserAttributes());
}
DirContextAdapter result = new DirContextAdapter(attrs, userDn,
ctxSource.getBaseLdapPath());