Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

SEC-2017: Convert IncorrectResultsSizeException.size() == 0 to BadCre…

…dentialsException in ActiveDirectoryAuthenticationProvider
  • Loading branch information...
commit e6593151fcedf1407e90709b347c8fceeafbe054 1 parent a5ec116
@rwinch rwinch authored
View
15 ...gframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java
@@ -12,6 +12,7 @@
*/
package org.springframework.security.ldap.authentication.ad;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.support.LdapUtils;
@@ -24,6 +25,7 @@
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
import org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider;
import org.springframework.util.Assert;
@@ -266,6 +268,7 @@ private BadCredentialsException badCredentials(Throwable cause) {
return (BadCredentialsException) badCredentials().initCause(cause);
}
+ @SuppressWarnings("deprecation")
private DirContextOperations searchForUser(DirContext ctx, String username) throws NamingException {
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
@@ -276,8 +279,18 @@ private DirContextOperations searchForUser(DirContext ctx, String username) thro
String searchRoot = rootDn != null ? rootDn : searchRootFromPrincipal(bindPrincipal);
- return SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx, searchCtls, searchRoot, searchFilter,
+ try {
+ return SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx, searchCtls, searchRoot, searchFilter,
new Object[]{bindPrincipal});
+ } catch (IncorrectResultSizeDataAccessException incorrectResults) {
+ if (incorrectResults.getActualSize() == 0) {
+ UsernameNotFoundException userNameNotFoundException = new UsernameNotFoundException("User " + username + " not found in directory.", username);
+ userNameNotFoundException.initCause(incorrectResults);
+ throw badCredentials(userNameNotFoundException);
+ }
+ // Search should never return multiple results if properly configured, so just rethrow
+ throw incorrectResults;
+ }
}
private String searchRootFromPrincipal(String bindPrincipal) {
View
34 ...ework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProviderTests.java
@@ -16,12 +16,14 @@
import static org.mockito.Mockito.*;
import static org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.ContextFactory;
+import org.apache.directory.shared.ldap.util.EmptyEnumeration;
import org.hamcrest.BaseMatcher;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.*;
import org.junit.rules.ExpectedException;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.security.authentication.AccountExpiredException;
@@ -32,6 +34,7 @@
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
@@ -125,6 +128,37 @@ public void failedUserSearchCausesBadCredentials() throws Exception {
provider.authenticate(joe);
}
+ // SEC-2017
+ @Test(expected = BadCredentialsException.class)
+ public void noUserSearchCausesUsernameNotFound() throws Exception {
+ DirContext ctx = mock(DirContext.class);
+ when(ctx.getNameInNamespace()).thenReturn("");
+ when(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
+ .thenReturn(new EmptyEnumeration<SearchResult>());
+
+ provider.contextFactory = createContextFactoryReturning(ctx);
+
+ provider.authenticate(joe);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test(expected = IncorrectResultSizeDataAccessException.class)
+ public void duplicateUserSearchCausesError() throws Exception {
+ DirContext ctx = mock(DirContext.class);
+ when(ctx.getNameInNamespace()).thenReturn("");
+ NamingEnumeration<SearchResult> searchResults = mock(NamingEnumeration.class);
+ when(searchResults.hasMore()).thenReturn(true,true,false);
+ SearchResult searchResult = mock(SearchResult.class);
+ when(searchResult.getName()).thenReturn("ou=1","ou=2");
+ when(searchResults.next()).thenReturn(searchResult);
+ when(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
+ .thenReturn(searchResults );
+
+ provider.contextFactory = createContextFactoryReturning(ctx);
+
+ provider.authenticate(joe);
+ }
+
static final String msg = "[LDAP: error code 49 - 80858585: LdapErr: DSID-DECAFF0, comment: AcceptSecurityContext error, data ";
@Test(expected = BadCredentialsException.class)
Please sign in to comment.
Something went wrong with that request. Please try again.