SEC-2017: Convert IncorrectResultsSizeException.size() == 0 to BadCredentialsException in ActiveDirectoryAuthenticationProvider
This commit is contained in:
parent
a5ec116e80
commit
e6593151fc
|
@ -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.authentication.UsernamePasswordAuthenticatio
|
|||
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 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
|
|||
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 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
|
|||
|
||||
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) {
|
||||
|
|
|
@ -16,12 +16,14 @@ import static org.junit.Assert.*;
|
|||
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.LockedException;
|
|||
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 class ActiveDirectoryLdapAuthenticationProviderTests {
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue