SEC-2915: Updated Java Code Formatting
This commit is contained in:
@@ -23,7 +23,6 @@ import javax.naming.directory.DirContext;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link LdapUtils}
|
||||
*
|
||||
@@ -31,57 +30,68 @@ import org.junit.Test;
|
||||
*/
|
||||
public class LdapUtilsTests {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void testCloseContextSwallowsNamingException() throws Exception {
|
||||
final DirContext dirCtx = mock(DirContext.class);
|
||||
doThrow(new NamingException()).when(dirCtx).close();
|
||||
@Test
|
||||
public void testCloseContextSwallowsNamingException() throws Exception {
|
||||
final DirContext dirCtx = mock(DirContext.class);
|
||||
doThrow(new NamingException()).when(dirCtx).close();
|
||||
|
||||
LdapUtils.closeContext(dirCtx);
|
||||
}
|
||||
LdapUtils.closeContext(dirCtx);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRelativeNameReturnsEmptyStringForDnEqualToBaseName() throws Exception {
|
||||
final DirContext mockCtx = mock(DirContext.class);
|
||||
@Test
|
||||
public void testGetRelativeNameReturnsEmptyStringForDnEqualToBaseName()
|
||||
throws Exception {
|
||||
final DirContext mockCtx = mock(DirContext.class);
|
||||
|
||||
when(mockCtx.getNameInNamespace()).thenReturn("dc=springframework,dc=org");
|
||||
when(mockCtx.getNameInNamespace()).thenReturn("dc=springframework,dc=org");
|
||||
|
||||
assertEquals("", LdapUtils.getRelativeName("dc=springframework,dc=org", mockCtx));
|
||||
}
|
||||
assertEquals("", LdapUtils.getRelativeName("dc=springframework,dc=org", mockCtx));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRelativeNameReturnsFullDnWithEmptyBaseName() throws Exception {
|
||||
final DirContext mockCtx = mock(DirContext.class);
|
||||
when(mockCtx.getNameInNamespace()).thenReturn("");
|
||||
@Test
|
||||
public void testGetRelativeNameReturnsFullDnWithEmptyBaseName() throws Exception {
|
||||
final DirContext mockCtx = mock(DirContext.class);
|
||||
when(mockCtx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
assertEquals("cn=jane,dc=springframework,dc=org",
|
||||
LdapUtils.getRelativeName("cn=jane,dc=springframework,dc=org", mockCtx));
|
||||
}
|
||||
assertEquals("cn=jane,dc=springframework,dc=org",
|
||||
LdapUtils.getRelativeName("cn=jane,dc=springframework,dc=org", mockCtx));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRelativeNameWorksWithArbitrarySpaces() throws Exception {
|
||||
final DirContext mockCtx = mock(DirContext.class);
|
||||
when(mockCtx.getNameInNamespace()).thenReturn("dc=springsecurity,dc = org");
|
||||
@Test
|
||||
public void testGetRelativeNameWorksWithArbitrarySpaces() throws Exception {
|
||||
final DirContext mockCtx = mock(DirContext.class);
|
||||
when(mockCtx.getNameInNamespace()).thenReturn("dc=springsecurity,dc = org");
|
||||
|
||||
assertEquals("cn=jane smith",
|
||||
LdapUtils.getRelativeName("cn=jane smith, dc = springsecurity , dc=org", mockCtx));
|
||||
}
|
||||
assertEquals("cn=jane smith", LdapUtils.getRelativeName(
|
||||
"cn=jane smith, dc = springsecurity , dc=org", mockCtx));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRootDnsAreParsedFromUrlsCorrectly() {
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine"));
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine:11389"));
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/"));
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/"));
|
||||
assertEquals("dc=springframework,dc=org",
|
||||
LdapUtils.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=springframework,dc=org"));
|
||||
assertEquals("dc=springframework,dc=org", LdapUtils.parseRootDnFromUrl("ldap:///dc=springframework,dc=org"));
|
||||
assertEquals("dc=springframework,dc=org",
|
||||
LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/dc=springframework,dc=org"));
|
||||
assertEquals("dc=springframework,dc=org/ou=blah",
|
||||
LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=springframework,dc=org/ou=blah"));
|
||||
assertEquals("dc=springframework,dc=org/ou=blah",
|
||||
LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk:389/dc=springframework,dc=org/ou=blah"));
|
||||
}
|
||||
@Test
|
||||
public void testRootDnsAreParsedFromUrlsCorrectly() {
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine"));
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine:11389"));
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/"));
|
||||
assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/"));
|
||||
assertEquals(
|
||||
"dc=springframework,dc=org",
|
||||
LdapUtils
|
||||
.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=springframework,dc=org"));
|
||||
assertEquals("dc=springframework,dc=org",
|
||||
LdapUtils.parseRootDnFromUrl("ldap:///dc=springframework,dc=org"));
|
||||
assertEquals(
|
||||
"dc=springframework,dc=org",
|
||||
LdapUtils
|
||||
.parseRootDnFromUrl("ldap://monkeymachine/dc=springframework,dc=org"));
|
||||
assertEquals(
|
||||
"dc=springframework,dc=org/ou=blah",
|
||||
LdapUtils
|
||||
.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=springframework,dc=org/ou=blah"));
|
||||
assertEquals(
|
||||
"dc=springframework,dc=org/ou=blah",
|
||||
LdapUtils
|
||||
.parseRootDnFromUrl("ldap://monkeymachine.co.uk:389/dc=springframework,dc=org/ou=blah"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,53 +18,56 @@ import org.junit.Test;
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class SpringSecurityAuthenticationSourceTests {
|
||||
@Before
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
@Before
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void principalAndCredentialsAreEmptyWithNoAuthentication() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
assertEquals("", source.getPrincipal());
|
||||
assertEquals("", source.getCredentials());
|
||||
}
|
||||
@Test
|
||||
public void principalAndCredentialsAreEmptyWithNoAuthentication() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
assertEquals("", source.getPrincipal());
|
||||
assertEquals("", source.getCredentials());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void principalIsEmptyForAnonymousUser() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
@Test
|
||||
public void principalIsEmptyForAnonymousUser() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new AnonymousAuthenticationToken("key", "anonUser", AuthorityUtils.createAuthorityList("ignored")));
|
||||
assertEquals("", source.getPrincipal());
|
||||
}
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new AnonymousAuthenticationToken("key", "anonUser", AuthorityUtils
|
||||
.createAuthorityList("ignored")));
|
||||
assertEquals("", source.getPrincipal());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void getPrincipalRejectsNonLdapUserDetailsObject() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken(new Object(), "password"));
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getPrincipalRejectsNonLdapUserDetailsObject() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken(new Object(), "password"));
|
||||
|
||||
source.getPrincipal();
|
||||
}
|
||||
source.getPrincipal();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedCredentialsAreReturned() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken(new Object(), "password"));
|
||||
@Test
|
||||
public void expectedCredentialsAreReturned() {
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken(new Object(), "password"));
|
||||
|
||||
assertEquals("password", source.getCredentials());
|
||||
}
|
||||
assertEquals("password", source.getCredentials());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedPrincipalIsReturned() {
|
||||
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence();
|
||||
user.setUsername("joe");
|
||||
user.setDn(new DistinguishedName("uid=joe,ou=users"));
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken(user.createUserDetails(), null));
|
||||
@Test
|
||||
public void expectedPrincipalIsReturned() {
|
||||
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence();
|
||||
user.setUsername("joe");
|
||||
user.setDn(new DistinguishedName("uid=joe,ou=users"));
|
||||
AuthenticationSource source = new SpringSecurityAuthenticationSource();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken(user.createUserDetails(), null));
|
||||
|
||||
assertEquals("uid=joe,ou=users", source.getPrincipal());
|
||||
}
|
||||
assertEquals("uid=joe,ou=users", source.getPrincipal());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,33 +36,36 @@ import org.springframework.ldap.core.DistinguishedName;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SpringSecurityLdapTemplateTests {
|
||||
|
||||
@Mock
|
||||
private DirContext ctx;
|
||||
@Captor
|
||||
private ArgumentCaptor<SearchControls> searchControls;
|
||||
@Mock
|
||||
private NamingEnumeration<SearchResult> resultsEnum;
|
||||
@Mock
|
||||
private SearchResult searchResult;
|
||||
@Mock
|
||||
private DirContext ctx;
|
||||
@Captor
|
||||
private ArgumentCaptor<SearchControls> searchControls;
|
||||
@Mock
|
||||
private NamingEnumeration<SearchResult> resultsEnum;
|
||||
@Mock
|
||||
private SearchResult searchResult;
|
||||
|
||||
// SEC-2405
|
||||
@Test
|
||||
public void searchForSingleEntryInternalAllowsReferrals() throws Exception {
|
||||
String base = "";
|
||||
String filter = "";
|
||||
String searchResultName = "ldap://example.com/dc=springframework,dc=org";
|
||||
Object[] params = new Object[] {};
|
||||
DirContextAdapter searchResultObject = mock(DirContextAdapter.class);
|
||||
// SEC-2405
|
||||
@Test
|
||||
public void searchForSingleEntryInternalAllowsReferrals() throws Exception {
|
||||
String base = "";
|
||||
String filter = "";
|
||||
String searchResultName = "ldap://example.com/dc=springframework,dc=org";
|
||||
Object[] params = new Object[] {};
|
||||
DirContextAdapter searchResultObject = mock(DirContextAdapter.class);
|
||||
|
||||
when(ctx.search(any(DistinguishedName.class), eq(filter), eq(params), searchControls.capture())).thenReturn(resultsEnum);
|
||||
when(resultsEnum.hasMore()).thenReturn(true, false);
|
||||
when(resultsEnum.next()).thenReturn(searchResult);
|
||||
when(searchResult.getName()).thenReturn(searchResultName);
|
||||
when(searchResult.getObject()).thenReturn(searchResultObject);
|
||||
when(
|
||||
ctx.search(any(DistinguishedName.class), eq(filter), eq(params),
|
||||
searchControls.capture())).thenReturn(resultsEnum);
|
||||
when(resultsEnum.hasMore()).thenReturn(true, false);
|
||||
when(resultsEnum.next()).thenReturn(searchResult);
|
||||
when(searchResult.getName()).thenReturn(searchResultName);
|
||||
when(searchResult.getObject()).thenReturn(searchResultObject);
|
||||
|
||||
SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx, mock(SearchControls.class), base, filter, params);
|
||||
SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx,
|
||||
mock(SearchControls.class), base, filter, params);
|
||||
|
||||
assertThat(searchControls.getValue().getReturningObjFlag()).isTrue();
|
||||
}
|
||||
assertThat(searchControls.getValue().getReturningObjFlag()).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
|
||||
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link LdapAuthenticationProvider}.
|
||||
*
|
||||
@@ -45,163 +44,193 @@ import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
|
||||
*/
|
||||
public class LdapAuthenticationProviderTests {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void testSupportsUsernamePasswordAuthenticationToken() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
|
||||
new MockAuthoritiesPopulator());
|
||||
@Test
|
||||
public void testSupportsUsernamePasswordAuthenticationToken() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
new MockAuthenticator(), new MockAuthoritiesPopulator());
|
||||
|
||||
assertTrue(ldapProvider.supports(UsernamePasswordAuthenticationToken.class));
|
||||
}
|
||||
assertTrue(ldapProvider.supports(UsernamePasswordAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultMapperIsSet() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
|
||||
new MockAuthoritiesPopulator());
|
||||
@Test
|
||||
public void testDefaultMapperIsSet() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
new MockAuthenticator(), new MockAuthoritiesPopulator());
|
||||
|
||||
assertTrue(ldapProvider.getUserDetailsContextMapper() instanceof LdapUserDetailsMapper);
|
||||
}
|
||||
assertTrue(ldapProvider.getUserDetailsContextMapper() instanceof LdapUserDetailsMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyOrNullUserNameThrowsException() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
|
||||
new MockAuthoritiesPopulator());
|
||||
@Test
|
||||
public void testEmptyOrNullUserNameThrowsException() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
new MockAuthenticator(), new MockAuthoritiesPopulator());
|
||||
|
||||
try {
|
||||
ldapProvider.authenticate(new UsernamePasswordAuthenticationToken(null, "password"));
|
||||
fail("Expected BadCredentialsException for empty username");
|
||||
} catch (BadCredentialsException expected) {}
|
||||
try {
|
||||
ldapProvider.authenticate(new UsernamePasswordAuthenticationToken(null,
|
||||
"password"));
|
||||
fail("Expected BadCredentialsException for empty username");
|
||||
}
|
||||
catch (BadCredentialsException expected) {
|
||||
}
|
||||
|
||||
try {
|
||||
ldapProvider.authenticate(new UsernamePasswordAuthenticationToken("", "bobspassword"));
|
||||
fail("Expected BadCredentialsException for null username");
|
||||
} catch (BadCredentialsException expected) {}
|
||||
}
|
||||
try {
|
||||
ldapProvider.authenticate(new UsernamePasswordAuthenticationToken("",
|
||||
"bobspassword"));
|
||||
fail("Expected BadCredentialsException for null username");
|
||||
}
|
||||
catch (BadCredentialsException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=BadCredentialsException.class)
|
||||
public void usernameNotFoundExceptionIsHiddenByDefault() {
|
||||
final LdapAuthenticator authenticator = mock(LdapAuthenticator.class);
|
||||
final UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken("joe", "password");
|
||||
when(authenticator.authenticate(joe)).thenThrow(new UsernameNotFoundException("nobody"));
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void usernameNotFoundExceptionIsHiddenByDefault() {
|
||||
final LdapAuthenticator authenticator = mock(LdapAuthenticator.class);
|
||||
final UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken(
|
||||
"joe", "password");
|
||||
when(authenticator.authenticate(joe)).thenThrow(
|
||||
new UsernameNotFoundException("nobody"));
|
||||
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(
|
||||
authenticator);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected=UsernameNotFoundException.class)
|
||||
public void usernameNotFoundExceptionIsNotHiddenIfConfigured() {
|
||||
final LdapAuthenticator authenticator = mock(LdapAuthenticator.class);
|
||||
final UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken("joe", "password");
|
||||
when(authenticator.authenticate(joe)).thenThrow(new UsernameNotFoundException("nobody"));
|
||||
@Test(expected = UsernameNotFoundException.class)
|
||||
public void usernameNotFoundExceptionIsNotHiddenIfConfigured() {
|
||||
final LdapAuthenticator authenticator = mock(LdapAuthenticator.class);
|
||||
final UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken(
|
||||
"joe", "password");
|
||||
when(authenticator.authenticate(joe)).thenThrow(
|
||||
new UsernameNotFoundException("nobody"));
|
||||
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
|
||||
provider.setHideUserNotFoundExceptions(false);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(
|
||||
authenticator);
|
||||
provider.setHideUserNotFoundExceptions(false);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalUsage() {
|
||||
MockAuthoritiesPopulator populator = new MockAuthoritiesPopulator();
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(), populator);
|
||||
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
|
||||
userMapper.setRoleAttributes(new String[] {"ou"});
|
||||
ldapProvider.setUserDetailsContextMapper(userMapper);
|
||||
@Test
|
||||
public void normalUsage() {
|
||||
MockAuthoritiesPopulator populator = new MockAuthoritiesPopulator();
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
new MockAuthenticator(), populator);
|
||||
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
|
||||
userMapper.setRoleAttributes(new String[] { "ou" });
|
||||
ldapProvider.setUserDetailsContextMapper(userMapper);
|
||||
|
||||
assertNotNull(ldapProvider.getAuthoritiesPopulator());
|
||||
assertNotNull(ldapProvider.getAuthoritiesPopulator());
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
|
||||
Object authDetails = new Object();
|
||||
authRequest.setDetails(authDetails);
|
||||
Authentication authResult = ldapProvider.authenticate(authRequest);
|
||||
assertEquals("benspassword", authResult.getCredentials());
|
||||
assertSame(authDetails, authResult.getDetails());
|
||||
UserDetails user = (UserDetails) authResult.getPrincipal();
|
||||
assertEquals(2, user.getAuthorities().size());
|
||||
assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", user.getPassword());
|
||||
assertEquals("ben", user.getUsername());
|
||||
assertEquals("ben", populator.getRequestedUsername());
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
|
||||
"ben", "benspassword");
|
||||
Object authDetails = new Object();
|
||||
authRequest.setDetails(authDetails);
|
||||
Authentication authResult = ldapProvider.authenticate(authRequest);
|
||||
assertEquals("benspassword", authResult.getCredentials());
|
||||
assertSame(authDetails, authResult.getDetails());
|
||||
UserDetails user = (UserDetails) authResult.getPrincipal();
|
||||
assertEquals(2, user.getAuthorities().size());
|
||||
assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", user.getPassword());
|
||||
assertEquals("ben", user.getUsername());
|
||||
assertEquals("ben", populator.getRequestedUsername());
|
||||
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains("ROLE_FROM_ENTRY"));
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains("ROLE_FROM_POPULATOR"));
|
||||
}
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains(
|
||||
"ROLE_FROM_ENTRY"));
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains(
|
||||
"ROLE_FROM_POPULATOR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passwordIsSetFromUserDataIfUseAuthenticationRequestCredentialsIsFalse() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
|
||||
new MockAuthoritiesPopulator());
|
||||
ldapProvider.setUseAuthenticationRequestCredentials(false);
|
||||
@Test
|
||||
public void passwordIsSetFromUserDataIfUseAuthenticationRequestCredentialsIsFalse() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
new MockAuthenticator(), new MockAuthoritiesPopulator());
|
||||
ldapProvider.setUseAuthenticationRequestCredentials(false);
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
|
||||
Authentication authResult = ldapProvider.authenticate(authRequest);
|
||||
assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", authResult.getCredentials());
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
|
||||
"ben", "benspassword");
|
||||
Authentication authResult = ldapProvider.authenticate(authRequest);
|
||||
assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", authResult.getCredentials());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useWithNullAuthoritiesPopulatorReturnsCorrectRole() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator());
|
||||
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
|
||||
userMapper.setRoleAttributes(new String[] {"ou"});
|
||||
ldapProvider.setUserDetailsContextMapper(userMapper);
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
|
||||
UserDetails user = (UserDetails) ldapProvider.authenticate(authRequest).getPrincipal();
|
||||
assertEquals(1, user.getAuthorities().size());
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains("ROLE_FROM_ENTRY"));
|
||||
}
|
||||
@Test
|
||||
public void useWithNullAuthoritiesPopulatorReturnsCorrectRole() {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
new MockAuthenticator());
|
||||
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
|
||||
userMapper.setRoleAttributes(new String[] { "ou" });
|
||||
ldapProvider.setUserDetailsContextMapper(userMapper);
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
|
||||
"ben", "benspassword");
|
||||
UserDetails user = (UserDetails) ldapProvider.authenticate(authRequest)
|
||||
.getPrincipal();
|
||||
assertEquals(1, user.getAuthorities().size());
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains(
|
||||
"ROLE_FROM_ENTRY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWithNamingException() {
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
|
||||
LdapAuthenticator mockAuthenticator = mock(LdapAuthenticator.class);
|
||||
CommunicationException expectedCause = new CommunicationException(new javax.naming.CommunicationException());
|
||||
when(mockAuthenticator.authenticate(authRequest)).thenThrow(expectedCause);
|
||||
@Test
|
||||
public void authenticateWithNamingException() {
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
|
||||
"ben", "benspassword");
|
||||
LdapAuthenticator mockAuthenticator = mock(LdapAuthenticator.class);
|
||||
CommunicationException expectedCause = new CommunicationException(
|
||||
new javax.naming.CommunicationException());
|
||||
when(mockAuthenticator.authenticate(authRequest)).thenThrow(expectedCause);
|
||||
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(mockAuthenticator);
|
||||
try {
|
||||
ldapProvider.authenticate(authRequest);
|
||||
fail("Expected Exception");
|
||||
} catch(InternalAuthenticationServiceException success) {
|
||||
assertSame(expectedCause, success.getCause());
|
||||
}
|
||||
}
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(
|
||||
mockAuthenticator);
|
||||
try {
|
||||
ldapProvider.authenticate(authRequest);
|
||||
fail("Expected Exception");
|
||||
}
|
||||
catch (InternalAuthenticationServiceException success) {
|
||||
assertSame(expectedCause, success.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
// ~ Inner Classes
|
||||
// ==================================================================================================
|
||||
|
||||
class MockAuthenticator implements LdapAuthenticator {
|
||||
class MockAuthenticator implements LdapAuthenticator {
|
||||
|
||||
public DirContextOperations authenticate(Authentication authentication) {
|
||||
DirContextAdapter ctx = new DirContextAdapter();
|
||||
ctx.setAttributeValue("ou", "FROM_ENTRY");
|
||||
String username = authentication.getName();
|
||||
String password = (String) authentication.getCredentials();
|
||||
public DirContextOperations authenticate(Authentication authentication) {
|
||||
DirContextAdapter ctx = new DirContextAdapter();
|
||||
ctx.setAttributeValue("ou", "FROM_ENTRY");
|
||||
String username = authentication.getName();
|
||||
String password = (String) authentication.getCredentials();
|
||||
|
||||
if (username.equals("ben") && password.equals("benspassword")) {
|
||||
ctx.setDn(new DistinguishedName(
|
||||
"cn=ben,ou=people,dc=springframework,dc=org"));
|
||||
ctx.setAttributeValue("userPassword", "{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=");
|
||||
|
||||
if (username.equals("ben") && password.equals("benspassword")) {
|
||||
ctx.setDn(new DistinguishedName("cn=ben,ou=people,dc=springframework,dc=org"));
|
||||
ctx.setAttributeValue("userPassword","{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=");
|
||||
return ctx;
|
||||
}
|
||||
else if (username.equals("jen") && password.equals("")) {
|
||||
ctx.setDn(new DistinguishedName(
|
||||
"cn=jen,ou=people,dc=springframework,dc=org"));
|
||||
|
||||
return ctx;
|
||||
} else if (username.equals("jen") && password.equals("")) {
|
||||
ctx.setDn(new DistinguishedName("cn=jen,ou=people,dc=springframework,dc=org"));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
throw new BadCredentialsException("Authentication failed.");
|
||||
}
|
||||
}
|
||||
|
||||
throw new BadCredentialsException("Authentication failed.");
|
||||
}
|
||||
}
|
||||
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||
String username;
|
||||
|
||||
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||
String username;
|
||||
public Collection<GrantedAuthority> getGrantedAuthorities(
|
||||
DirContextOperations userCtx, String username) {
|
||||
this.username = username;
|
||||
return AuthorityUtils.createAuthorityList("ROLE_FROM_POPULATOR");
|
||||
}
|
||||
|
||||
public Collection<GrantedAuthority> getGrantedAuthorities(DirContextOperations userCtx, String username) {
|
||||
this.username = username;
|
||||
return AuthorityUtils.createAuthorityList("ROLE_FROM_POPULATOR");
|
||||
}
|
||||
|
||||
String getRequestedUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
String getRequestedUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,95 +21,113 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link LdapShaPasswordEncoder}.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class LdapShaPasswordEncoderTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
LdapShaPasswordEncoder sha;
|
||||
LdapShaPasswordEncoder sha;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
sha = new LdapShaPasswordEncoder();
|
||||
}
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
sha = new LdapShaPasswordEncoder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidPasswordFails() {
|
||||
assertFalse(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "wrongpassword", null));
|
||||
}
|
||||
@Test
|
||||
public void invalidPasswordFails() {
|
||||
assertFalse(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
"wrongpassword", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidSaltedPasswordFails() {
|
||||
assertFalse(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "wrongpassword", null));
|
||||
assertFalse(sha.isPasswordValid("{SSHA}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd", "wrongpassword", null));
|
||||
}
|
||||
@Test
|
||||
public void invalidSaltedPasswordFails() {
|
||||
assertFalse(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX",
|
||||
"wrongpassword", null));
|
||||
assertFalse(sha.isPasswordValid("{SSHA}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd",
|
||||
"wrongpassword", null));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void nonByteArraySaltThrowsException() {
|
||||
sha.encodePassword("password", "AStringNotAByteArray");
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void nonByteArraySaltThrowsException() {
|
||||
sha.encodePassword("password", "AStringNotAByteArray");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test values generated by 'slappasswd -h {SHA} -s boabspasswurd'
|
||||
*/
|
||||
@Test
|
||||
public void validPasswordSucceeds() {
|
||||
sha.setForceLowerCasePrefix(false);
|
||||
assertTrue(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{sha}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "boabspasswurd", null));
|
||||
sha.setForceLowerCasePrefix(true);
|
||||
assertTrue(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{sha}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "boabspasswurd", null));
|
||||
}
|
||||
/**
|
||||
* Test values generated by 'slappasswd -h {SHA} -s boabspasswurd'
|
||||
*/
|
||||
@Test
|
||||
public void validPasswordSucceeds() {
|
||||
sha.setForceLowerCasePrefix(false);
|
||||
assertTrue(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
"boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{sha}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
"boabspasswurd", null));
|
||||
sha.setForceLowerCasePrefix(true);
|
||||
assertTrue(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
"boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{sha}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
"boabspasswurd", null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test values generated by 'slappasswd -s boabspasswurd'
|
||||
*/
|
||||
@Test
|
||||
public void validSaltedPasswordSucceeds() {
|
||||
sha.setForceLowerCasePrefix(false);
|
||||
assertTrue(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{ssha}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd", "boabspasswurd", null));
|
||||
sha.setForceLowerCasePrefix(true);
|
||||
assertTrue(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{ssha}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd", "boabspasswurd", null));
|
||||
}
|
||||
/**
|
||||
* Test values generated by 'slappasswd -s boabspasswurd'
|
||||
*/
|
||||
@Test
|
||||
public void validSaltedPasswordSucceeds() {
|
||||
sha.setForceLowerCasePrefix(false);
|
||||
assertTrue(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX",
|
||||
"boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{ssha}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd",
|
||||
"boabspasswurd", null));
|
||||
sha.setForceLowerCasePrefix(true);
|
||||
assertTrue(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX",
|
||||
"boabspasswurd", null));
|
||||
assertTrue(sha.isPasswordValid("{ssha}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd",
|
||||
"boabspasswurd", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
// SEC-1031
|
||||
public void fullLengthOfHashIsUsedInComparison() throws Exception {
|
||||
// Change the first hash character from '2' to '3'
|
||||
assertFalse(sha.isPasswordValid("{SSHA}35ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "boabspasswurd", null));
|
||||
// Change the last hash character from 'X' to 'Y'
|
||||
assertFalse(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgY", "boabspasswurd", null));
|
||||
}
|
||||
@Test
|
||||
// SEC-1031
|
||||
public void fullLengthOfHashIsUsedInComparison() throws Exception {
|
||||
// Change the first hash character from '2' to '3'
|
||||
assertFalse(sha.isPasswordValid("{SSHA}35ro4PKC8jhQZ26jVsozhX/xaP0suHgX",
|
||||
"boabspasswurd", null));
|
||||
// Change the last hash character from 'X' to 'Y'
|
||||
assertFalse(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgY",
|
||||
"boabspasswurd", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctPrefixCaseIsUsed() {
|
||||
sha.setForceLowerCasePrefix(false);
|
||||
assertEquals("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", sha.encodePassword("boabspasswurd", null));
|
||||
assertTrue(sha.encodePassword("somepassword", "salt".getBytes()).startsWith("{SSHA}"));
|
||||
@Test
|
||||
public void correctPrefixCaseIsUsed() {
|
||||
sha.setForceLowerCasePrefix(false);
|
||||
assertEquals("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
sha.encodePassword("boabspasswurd", null));
|
||||
assertTrue(sha.encodePassword("somepassword", "salt".getBytes()).startsWith(
|
||||
"{SSHA}"));
|
||||
|
||||
sha.setForceLowerCasePrefix(true);
|
||||
assertEquals("{sha}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", sha.encodePassword("boabspasswurd", null));
|
||||
assertTrue(sha.encodePassword("somepassword", "salt".getBytes()).startsWith("{ssha}"));
|
||||
sha.setForceLowerCasePrefix(true);
|
||||
assertEquals("{sha}ddSFGmjXYPbZC+NXR2kCzBRjqiE=",
|
||||
sha.encodePassword("boabspasswurd", null));
|
||||
assertTrue(sha.encodePassword("somepassword", "salt".getBytes()).startsWith(
|
||||
"{ssha}"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void invalidPrefixIsRejected() {
|
||||
sha.isPasswordValid("{MD9}xxxxxxxxxx" , "somepassword", null);
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void invalidPrefixIsRejected() {
|
||||
sha.isPasswordValid("{MD9}xxxxxxxxxx", "somepassword", null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void malformedPrefixIsRejected() {
|
||||
// No right brace
|
||||
sha.isPasswordValid("{SSHA25ro4PKC8jhQZ26jVsozhX/xaP0suHgX" , "somepassword", null);
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void malformedPrefixIsRejected() {
|
||||
// No right brace
|
||||
sha.isPasswordValid("{SSHA25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "somepassword", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,29 +19,31 @@ import org.springframework.security.ldap.search.LdapUserSearch;
|
||||
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class MockUserSearch implements LdapUserSearch {
|
||||
//~ Instance fields ================================================================================================
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
DirContextOperations user;
|
||||
DirContextOperations user;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public MockUserSearch() {
|
||||
}
|
||||
public MockUserSearch() {
|
||||
}
|
||||
|
||||
public MockUserSearch(DirContextOperations user) {
|
||||
this.user = user;
|
||||
}
|
||||
public MockUserSearch(DirContextOperations user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public DirContextOperations searchForUser(String username) {
|
||||
return user;
|
||||
}
|
||||
public DirContextOperations searchForUser(String username) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,39 +29,42 @@ import org.junit.Test;
|
||||
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class PasswordComparisonAuthenticatorMockTests {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void ldapCompareOperationIsUsedWhenPasswordIsNotRetrieved() throws Exception {
|
||||
final DirContext dirCtx = mock(DirContext.class);
|
||||
final BaseLdapPathContextSource source = mock(BaseLdapPathContextSource.class);
|
||||
final BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("uid", "bob"));
|
||||
@Test
|
||||
public void ldapCompareOperationIsUsedWhenPasswordIsNotRetrieved() throws Exception {
|
||||
final DirContext dirCtx = mock(DirContext.class);
|
||||
final BaseLdapPathContextSource source = mock(BaseLdapPathContextSource.class);
|
||||
final BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("uid", "bob"));
|
||||
|
||||
PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(source);
|
||||
PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(
|
||||
source);
|
||||
|
||||
authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"});
|
||||
authenticator.setUserDnPatterns(new String[] { "cn={0},ou=people" });
|
||||
|
||||
// Get the mock to return an empty attribute set
|
||||
when(source.getReadOnlyContext()).thenReturn(dirCtx);
|
||||
when(dirCtx.getAttributes(eq("cn=Bob,ou=people"), any(String[].class))).thenReturn(attrs);
|
||||
when(dirCtx.getNameInNamespace()).thenReturn("dc=springframework,dc=org");
|
||||
// Get the mock to return an empty attribute set
|
||||
when(source.getReadOnlyContext()).thenReturn(dirCtx);
|
||||
when(dirCtx.getAttributes(eq("cn=Bob,ou=people"), any(String[].class)))
|
||||
.thenReturn(attrs);
|
||||
when(dirCtx.getNameInNamespace()).thenReturn("dc=springframework,dc=org");
|
||||
|
||||
// Setup a single return value (i.e. success)
|
||||
final NamingEnumeration searchResults = new BasicAttributes("", null).getAll();
|
||||
// Setup a single return value (i.e. success)
|
||||
final NamingEnumeration searchResults = new BasicAttributes("", null).getAll();
|
||||
|
||||
when(dirCtx.search(eq("cn=Bob,ou=people"),
|
||||
eq("(userPassword={0})"),
|
||||
any(Object[].class),
|
||||
any(SearchControls.class))).thenReturn(searchResults);
|
||||
when(
|
||||
dirCtx.search(eq("cn=Bob,ou=people"), eq("(userPassword={0})"),
|
||||
any(Object[].class), any(SearchControls.class))).thenReturn(
|
||||
searchResults);
|
||||
|
||||
authenticator.authenticate(new UsernamePasswordAuthenticationToken("Bob","bobspassword"));
|
||||
}
|
||||
authenticator.authenticate(new UsernamePasswordAuthenticationToken("Bob",
|
||||
"bobspassword"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,367 +57,413 @@ import static org.springframework.security.ldap.authentication.ad.ActiveDirector
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class ActiveDirectoryLdapAuthenticationProviderTests {
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider provider;
|
||||
UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken("joe", "password");
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
provider = new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu", "ldap://192.168.1.200/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindPrincipalIsCreatedCorrectly() throws Exception {
|
||||
assertEquals("joe@mydomain.eu", provider.createBindPrincipal("joe"));
|
||||
assertEquals("joe@mydomain.eu", provider.createBindPrincipal("joe@mydomain.eu"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successfulAuthenticationProducesExpectedAuthorities() throws Exception {
|
||||
checkAuthentication("dc=mydomain,dc=eu", provider);
|
||||
}
|
||||
|
||||
// SEC-1915
|
||||
@Test
|
||||
public void customSearchFilterIsUsedForSuccessfulAuthentication() throws Exception {
|
||||
//given
|
||||
String customSearchFilter = "(&(objectClass=user)(sAMAccountName={0}))";
|
||||
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
|
||||
when(ctx.search(any(Name.class), eq(customSearchFilter), any(Object[].class), any(SearchControls.class)))
|
||||
.thenReturn(new MockNamingEnumeration(sr));
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider customProvider
|
||||
= new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu", "ldap://192.168.1.200/");
|
||||
customProvider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
//when
|
||||
customProvider.setSearchFilter(customSearchFilter);
|
||||
Authentication result = customProvider.authenticate(joe);
|
||||
|
||||
//then
|
||||
assertTrue(result.isAuthenticated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultSearchFilter() throws Exception {
|
||||
//given
|
||||
final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
|
||||
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
|
||||
when(ctx.search(any(Name.class), eq(defaultSearchFilter), any(Object[].class), any(SearchControls.class)))
|
||||
.thenReturn(new MockNamingEnumeration(sr));
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider customProvider
|
||||
= new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu", "ldap://192.168.1.200/");
|
||||
customProvider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
//when
|
||||
Authentication result = customProvider.authenticate(joe);
|
||||
|
||||
//then
|
||||
assertTrue(result.isAuthenticated());
|
||||
verify(ctx).search(any(DistinguishedName.class), eq(defaultSearchFilter), any(Object[].class), any(SearchControls.class));
|
||||
}
|
||||
|
||||
// SEC-2897
|
||||
@Test
|
||||
public void bindPrincipalUsed() throws Exception {
|
||||
//given
|
||||
final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
|
||||
ArgumentCaptor<Object[]> captor = ArgumentCaptor.forClass(Object[].class);
|
||||
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
|
||||
when(ctx.search(any(Name.class), eq(defaultSearchFilter), captor.capture(), any(SearchControls.class)))
|
||||
.thenReturn(new MockNamingEnumeration(sr));
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider customProvider
|
||||
= new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu", "ldap://192.168.1.200/");
|
||||
customProvider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
//when
|
||||
Authentication result = customProvider.authenticate(joe);
|
||||
|
||||
//then
|
||||
assertThat(captor.getValue()).containsOnly("joe@mydomain.eu");
|
||||
assertTrue(result.isAuthenticated());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void setSearchFilterNull() {
|
||||
provider.setSearchFilter(null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void setSearchFilterEmpty() {
|
||||
provider.setSearchFilter(" ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullDomainIsSupportedIfAuthenticatingWithFullUserPrincipal() throws Exception {
|
||||
provider = new ActiveDirectoryLdapAuthenticationProvider(null, "ldap://192.168.1.200/");
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
|
||||
when(ctx.search(eq(new DistinguishedName("DC=mydomain,DC=eu")), any(String.class), any(Object[].class), any(SearchControls.class)))
|
||||
.thenReturn(new MockNamingEnumeration(sr));
|
||||
provider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
try {
|
||||
provider.authenticate(joe);
|
||||
fail("Expected BadCredentialsException for user with no domain information");
|
||||
} catch (BadCredentialsException expected) {
|
||||
}
|
||||
|
||||
provider.authenticate(new UsernamePasswordAuthenticationToken("joe@mydomain.eu", "password"));
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void failedUserSearchCausesBadCredentials() 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)))
|
||||
.thenThrow(new NameNotFoundException());
|
||||
|
||||
provider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// SEC-2500
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void sec2500PreventAnonymousBind() {
|
||||
provider.authenticate(new UsernamePasswordAuthenticationToken("rwinch", ""));
|
||||
}
|
||||
|
||||
@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.getObject()).thenReturn(new DirContextAdapter("ou=1"),new DirContextAdapter("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)
|
||||
public void userNotFoundIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "525, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void incorrectPasswordIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "52e, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void notPermittedIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "530, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passwordNeedsResetIsCorrectlyMapped() {
|
||||
final String dataCode = "773";
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + dataCode+", xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
|
||||
thrown.expect(BadCredentialsException.class);
|
||||
thrown.expect(new BaseMatcher<BadCredentialsException>() {
|
||||
private Matcher<Object> causeInstance = CoreMatchers.instanceOf(ActiveDirectoryAuthenticationException.class);
|
||||
private Matcher<String> causeDataCode = CoreMatchers.equalTo(dataCode);
|
||||
public boolean matches(Object that) {
|
||||
Throwable t = (Throwable) that;
|
||||
ActiveDirectoryAuthenticationException cause = (ActiveDirectoryAuthenticationException) t.getCause();
|
||||
return causeInstance.matches(cause) && causeDataCode.matches(cause.getDataCode());
|
||||
}
|
||||
|
||||
public void describeTo(Description desc) {
|
||||
desc.appendText("getCause() ");
|
||||
causeInstance.describeTo(desc);
|
||||
desc.appendText("getCause().getDataCode() ");
|
||||
causeDataCode.describeTo(desc);
|
||||
}
|
||||
});
|
||||
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = CredentialsExpiredException.class)
|
||||
public void expiredPasswordIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "532, xxxx]"));
|
||||
|
||||
try {
|
||||
provider.authenticate(joe);
|
||||
fail();
|
||||
} catch (BadCredentialsException expected) {
|
||||
}
|
||||
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = DisabledException.class)
|
||||
public void accountDisabledIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "533, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = AccountExpiredException.class)
|
||||
public void accountExpiredIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "701, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = LockedException.class)
|
||||
public void accountLockedIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "775, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void unknownErrorCodeIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg + "999, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void errorWithNoSubcodeIsHandledCleanly() throws Exception {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(msg));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = org.springframework.ldap.CommunicationException.class)
|
||||
public void nonAuthenticationExceptionIsConvertedToSpringLdapException() throws Exception {
|
||||
provider.contextFactory = createContextFactoryThrowing(new CommunicationException(msg));
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rootDnProvidedSeparatelyFromDomainAlsoWorks() throws Exception {
|
||||
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu", "ldap://192.168.1.200/", "dc=ad,dc=eu,dc=mydomain");
|
||||
checkAuthentication("dc=ad,dc=eu,dc=mydomain", provider);
|
||||
|
||||
}
|
||||
|
||||
ContextFactory createContextFactoryThrowing(final NamingException e) {
|
||||
return new ContextFactory() {
|
||||
@Override
|
||||
DirContext createContext(Hashtable<?, ?> env) throws NamingException {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
ContextFactory createContextFactoryReturning(final DirContext ctx) {
|
||||
return new ContextFactory() {
|
||||
@Override
|
||||
DirContext createContext(Hashtable<?, ?> env) throws NamingException {
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void checkAuthentication(String rootDn, ActiveDirectoryLdapAuthenticationProvider provider) throws NamingException {
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
|
||||
@SuppressWarnings("deprecation") DistinguishedName searchBaseDn = new DistinguishedName(rootDn);
|
||||
when(ctx.search(eq(searchBaseDn), any(String.class), any(Object[].class), any(SearchControls.class)))
|
||||
.thenReturn(new MockNamingEnumeration(sr))
|
||||
.thenReturn(new MockNamingEnumeration(sr));
|
||||
|
||||
provider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
Authentication result = provider.authenticate(joe);
|
||||
|
||||
assertEquals(0, result.getAuthorities().size());
|
||||
|
||||
dca.addAttributeValue("memberOf","CN=Admin,CN=Users,DC=mydomain,DC=eu");
|
||||
|
||||
result = provider.authenticate(joe);
|
||||
|
||||
assertEquals(1, result.getAuthorities().size());
|
||||
}
|
||||
|
||||
static class MockNamingEnumeration implements NamingEnumeration<SearchResult> {
|
||||
private SearchResult sr;
|
||||
|
||||
public MockNamingEnumeration(SearchResult sr) {
|
||||
this.sr = sr;
|
||||
}
|
||||
|
||||
public SearchResult next() {
|
||||
SearchResult result = sr;
|
||||
sr = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return sr != null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return hasMore();
|
||||
}
|
||||
|
||||
public SearchResult nextElement() {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider provider;
|
||||
UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken(
|
||||
"joe", "password");
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
provider = new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu",
|
||||
"ldap://192.168.1.200/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindPrincipalIsCreatedCorrectly() throws Exception {
|
||||
assertEquals("joe@mydomain.eu", provider.createBindPrincipal("joe"));
|
||||
assertEquals("joe@mydomain.eu", provider.createBindPrincipal("joe@mydomain.eu"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successfulAuthenticationProducesExpectedAuthorities() throws Exception {
|
||||
checkAuthentication("dc=mydomain,dc=eu", provider);
|
||||
}
|
||||
|
||||
// SEC-1915
|
||||
@Test
|
||||
public void customSearchFilterIsUsedForSuccessfulAuthentication() throws Exception {
|
||||
// given
|
||||
String customSearchFilter = "(&(objectClass=user)(sAMAccountName={0}))";
|
||||
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca,
|
||||
dca.getAttributes());
|
||||
when(
|
||||
ctx.search(any(Name.class), eq(customSearchFilter), any(Object[].class),
|
||||
any(SearchControls.class))).thenReturn(
|
||||
new MockNamingEnumeration(sr));
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
|
||||
"mydomain.eu", "ldap://192.168.1.200/");
|
||||
customProvider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
// when
|
||||
customProvider.setSearchFilter(customSearchFilter);
|
||||
Authentication result = customProvider.authenticate(joe);
|
||||
|
||||
// then
|
||||
assertTrue(result.isAuthenticated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultSearchFilter() throws Exception {
|
||||
// given
|
||||
final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
|
||||
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca,
|
||||
dca.getAttributes());
|
||||
when(
|
||||
ctx.search(any(Name.class), eq(defaultSearchFilter), any(Object[].class),
|
||||
any(SearchControls.class))).thenReturn(
|
||||
new MockNamingEnumeration(sr));
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
|
||||
"mydomain.eu", "ldap://192.168.1.200/");
|
||||
customProvider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
// when
|
||||
Authentication result = customProvider.authenticate(joe);
|
||||
|
||||
// then
|
||||
assertTrue(result.isAuthenticated());
|
||||
verify(ctx).search(any(DistinguishedName.class), eq(defaultSearchFilter),
|
||||
any(Object[].class), any(SearchControls.class));
|
||||
}
|
||||
|
||||
// SEC-2897
|
||||
@Test
|
||||
public void bindPrincipalUsed() throws Exception {
|
||||
// given
|
||||
final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
|
||||
ArgumentCaptor<Object[]> captor = ArgumentCaptor.forClass(Object[].class);
|
||||
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca,
|
||||
dca.getAttributes());
|
||||
when(
|
||||
ctx.search(any(Name.class), eq(defaultSearchFilter), captor.capture(),
|
||||
any(SearchControls.class))).thenReturn(
|
||||
new MockNamingEnumeration(sr));
|
||||
|
||||
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
|
||||
"mydomain.eu", "ldap://192.168.1.200/");
|
||||
customProvider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
// when
|
||||
Authentication result = customProvider.authenticate(joe);
|
||||
|
||||
// then
|
||||
assertThat(captor.getValue()).containsOnly("joe@mydomain.eu");
|
||||
assertTrue(result.isAuthenticated());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void setSearchFilterNull() {
|
||||
provider.setSearchFilter(null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void setSearchFilterEmpty() {
|
||||
provider.setSearchFilter(" ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullDomainIsSupportedIfAuthenticatingWithFullUserPrincipal()
|
||||
throws Exception {
|
||||
provider = new ActiveDirectoryLdapAuthenticationProvider(null,
|
||||
"ldap://192.168.1.200/");
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca,
|
||||
dca.getAttributes());
|
||||
when(
|
||||
ctx.search(eq(new DistinguishedName("DC=mydomain,DC=eu")),
|
||||
any(String.class), any(Object[].class), any(SearchControls.class)))
|
||||
.thenReturn(new MockNamingEnumeration(sr));
|
||||
provider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
try {
|
||||
provider.authenticate(joe);
|
||||
fail("Expected BadCredentialsException for user with no domain information");
|
||||
}
|
||||
catch (BadCredentialsException expected) {
|
||||
}
|
||||
|
||||
provider.authenticate(new UsernamePasswordAuthenticationToken("joe@mydomain.eu",
|
||||
"password"));
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void failedUserSearchCausesBadCredentials() 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)))
|
||||
.thenThrow(new NameNotFoundException());
|
||||
|
||||
provider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// SEC-2500
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void sec2500PreventAnonymousBind() {
|
||||
provider.authenticate(new UsernamePasswordAuthenticationToken("rwinch", ""));
|
||||
}
|
||||
|
||||
@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.getObject()).thenReturn(new DirContextAdapter("ou=1"),
|
||||
new DirContextAdapter("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)
|
||||
public void userNotFoundIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "525, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void incorrectPasswordIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "52e, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void notPermittedIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "530, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passwordNeedsResetIsCorrectlyMapped() {
|
||||
final String dataCode = "773";
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + dataCode + ", xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
|
||||
thrown.expect(BadCredentialsException.class);
|
||||
thrown.expect(new BaseMatcher<BadCredentialsException>() {
|
||||
private Matcher<Object> causeInstance = CoreMatchers
|
||||
.instanceOf(ActiveDirectoryAuthenticationException.class);
|
||||
private Matcher<String> causeDataCode = CoreMatchers.equalTo(dataCode);
|
||||
|
||||
public boolean matches(Object that) {
|
||||
Throwable t = (Throwable) that;
|
||||
ActiveDirectoryAuthenticationException cause = (ActiveDirectoryAuthenticationException) t
|
||||
.getCause();
|
||||
return causeInstance.matches(cause)
|
||||
&& causeDataCode.matches(cause.getDataCode());
|
||||
}
|
||||
|
||||
public void describeTo(Description desc) {
|
||||
desc.appendText("getCause() ");
|
||||
causeInstance.describeTo(desc);
|
||||
desc.appendText("getCause().getDataCode() ");
|
||||
causeDataCode.describeTo(desc);
|
||||
}
|
||||
});
|
||||
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = CredentialsExpiredException.class)
|
||||
public void expiredPasswordIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "532, xxxx]"));
|
||||
|
||||
try {
|
||||
provider.authenticate(joe);
|
||||
fail();
|
||||
}
|
||||
catch (BadCredentialsException expected) {
|
||||
}
|
||||
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = DisabledException.class)
|
||||
public void accountDisabledIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "533, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = AccountExpiredException.class)
|
||||
public void accountExpiredIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "701, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = LockedException.class)
|
||||
public void accountLockedIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "775, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void unknownErrorCodeIsCorrectlyMapped() {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg + "999, xxxx]"));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void errorWithNoSubcodeIsHandledCleanly() throws Exception {
|
||||
provider.contextFactory = createContextFactoryThrowing(new AuthenticationException(
|
||||
msg));
|
||||
provider.setConvertSubErrorCodesToExceptions(true);
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test(expected = org.springframework.ldap.CommunicationException.class)
|
||||
public void nonAuthenticationExceptionIsConvertedToSpringLdapException()
|
||||
throws Exception {
|
||||
provider.contextFactory = createContextFactoryThrowing(new CommunicationException(
|
||||
msg));
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rootDnProvidedSeparatelyFromDomainAlsoWorks() throws Exception {
|
||||
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
|
||||
"mydomain.eu", "ldap://192.168.1.200/", "dc=ad,dc=eu,dc=mydomain");
|
||||
checkAuthentication("dc=ad,dc=eu,dc=mydomain", provider);
|
||||
|
||||
}
|
||||
|
||||
ContextFactory createContextFactoryThrowing(final NamingException e) {
|
||||
return new ContextFactory() {
|
||||
@Override
|
||||
DirContext createContext(Hashtable<?, ?> env) throws NamingException {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ContextFactory createContextFactoryReturning(final DirContext ctx) {
|
||||
return new ContextFactory() {
|
||||
@Override
|
||||
DirContext createContext(Hashtable<?, ?> env) throws NamingException {
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void checkAuthentication(String rootDn,
|
||||
ActiveDirectoryLdapAuthenticationProvider provider) throws NamingException {
|
||||
DirContext ctx = mock(DirContext.class);
|
||||
when(ctx.getNameInNamespace()).thenReturn("");
|
||||
|
||||
DirContextAdapter dca = new DirContextAdapter();
|
||||
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca,
|
||||
dca.getAttributes());
|
||||
@SuppressWarnings("deprecation")
|
||||
DistinguishedName searchBaseDn = new DistinguishedName(rootDn);
|
||||
when(
|
||||
ctx.search(eq(searchBaseDn), any(String.class), any(Object[].class),
|
||||
any(SearchControls.class))).thenReturn(
|
||||
new MockNamingEnumeration(sr)).thenReturn(new MockNamingEnumeration(sr));
|
||||
|
||||
provider.contextFactory = createContextFactoryReturning(ctx);
|
||||
|
||||
Authentication result = provider.authenticate(joe);
|
||||
|
||||
assertEquals(0, result.getAuthorities().size());
|
||||
|
||||
dca.addAttributeValue("memberOf", "CN=Admin,CN=Users,DC=mydomain,DC=eu");
|
||||
|
||||
result = provider.authenticate(joe);
|
||||
|
||||
assertEquals(1, result.getAuthorities().size());
|
||||
}
|
||||
|
||||
static class MockNamingEnumeration implements NamingEnumeration<SearchResult> {
|
||||
private SearchResult sr;
|
||||
|
||||
public MockNamingEnumeration(SearchResult sr) {
|
||||
this.sr = sr;
|
||||
}
|
||||
|
||||
public SearchResult next() {
|
||||
SearchResult result = sr;
|
||||
sr = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return sr != null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return hasMore();
|
||||
}
|
||||
|
||||
public SearchResult nextElement() {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,52 +15,44 @@ import org.springframework.security.ldap.userdetails.LdapUserDetailsImpl;
|
||||
/**
|
||||
* Test cases which run against an OpenLDAP server.
|
||||
* <p>
|
||||
* Run the script in the module root to start the server and import the data before running.
|
||||
* Run the script in the module root to start the server and import the data before
|
||||
* running.
|
||||
* @author Luke Taylor
|
||||
* @since 3.0
|
||||
*/
|
||||
public class OpenLDAPIntegrationTestSuite {
|
||||
PasswordPolicyAwareContextSource cs;
|
||||
/*
|
||||
@Before
|
||||
public void createContextSource() throws Exception {
|
||||
cs = new PasswordPolicyAwareContextSource("ldap://localhost:22389/dc=springsource,dc=com");
|
||||
cs.setUserDn("cn=admin,dc=springsource,dc=com");
|
||||
cs.setPassword("password");
|
||||
cs.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleBindSucceeds() throws Exception {
|
||||
BindAuthenticator authenticator = new BindAuthenticator(cs);
|
||||
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=users"});
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
|
||||
provider.authenticate(new UsernamePasswordAuthenticationToken("luke","password"));
|
||||
}
|
||||
|
||||
@Test(expected=LockedException.class)
|
||||
public void repeatedBindWithWrongPasswordLocksAccount() throws Exception {
|
||||
BindAuthenticator authenticator = new BindAuthenticator(cs);
|
||||
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=users"});
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
|
||||
for (int count=1; count < 4; count++) {
|
||||
try {
|
||||
Authentication a = provider.authenticate(new UsernamePasswordAuthenticationToken("lockme","wrong"));
|
||||
LdapUserDetailsImpl ud = (LdapUserDetailsImpl) a.getPrincipal();
|
||||
assertTrue(ud.getTimeBeforeExpiration() < Integer.MAX_VALUE && ud.getTimeBeforeExpiration() > 0);
|
||||
} catch (BadCredentialsException expected) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passwordExpiryTimeIsDetectedCorrectly() throws Exception {
|
||||
BindAuthenticator authenticator = new BindAuthenticator(cs);
|
||||
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=users"});
|
||||
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
|
||||
Authentication a = provider.authenticate(new UsernamePasswordAuthenticationToken("expireme","password"));
|
||||
PasswordPolicyData ud = (LdapUserDetailsImpl) a.getPrincipal();
|
||||
assertTrue(ud.getTimeBeforeExpiration() < Integer.MAX_VALUE && ud.getTimeBeforeExpiration() > 0);
|
||||
}
|
||||
*/
|
||||
PasswordPolicyAwareContextSource cs;
|
||||
/*
|
||||
* @Before public void createContextSource() throws Exception { cs = new
|
||||
* PasswordPolicyAwareContextSource("ldap://localhost:22389/dc=springsource,dc=com");
|
||||
* cs.setUserDn("cn=admin,dc=springsource,dc=com"); cs.setPassword("password");
|
||||
* cs.afterPropertiesSet(); }
|
||||
*
|
||||
* @Test public void simpleBindSucceeds() throws Exception { BindAuthenticator
|
||||
* authenticator = new BindAuthenticator(cs); authenticator.setUserDnPatterns(new
|
||||
* String[] {"uid={0},ou=users"}); LdapAuthenticationProvider provider = new
|
||||
* LdapAuthenticationProvider(authenticator); provider.authenticate(new
|
||||
* UsernamePasswordAuthenticationToken("luke","password")); }
|
||||
*
|
||||
* @Test(expected=LockedException.class) public void
|
||||
* repeatedBindWithWrongPasswordLocksAccount() throws Exception { BindAuthenticator
|
||||
* authenticator = new BindAuthenticator(cs); authenticator.setUserDnPatterns(new
|
||||
* String[] {"uid={0},ou=users"}); LdapAuthenticationProvider provider = new
|
||||
* LdapAuthenticationProvider(authenticator); for (int count=1; count < 4; count++) {
|
||||
* try { Authentication a = provider.authenticate(new
|
||||
* UsernamePasswordAuthenticationToken("lockme","wrong")); LdapUserDetailsImpl ud =
|
||||
* (LdapUserDetailsImpl) a.getPrincipal(); assertTrue(ud.getTimeBeforeExpiration() <
|
||||
* Integer.MAX_VALUE && ud.getTimeBeforeExpiration() > 0); } catch
|
||||
* (BadCredentialsException expected) { } } }
|
||||
*
|
||||
* @Test public void passwordExpiryTimeIsDetectedCorrectly() throws Exception {
|
||||
* BindAuthenticator authenticator = new BindAuthenticator(cs);
|
||||
* authenticator.setUserDnPatterns(new String[] {"uid={0},ou=users"});
|
||||
* LdapAuthenticationProvider provider = new
|
||||
* LdapAuthenticationProvider(authenticator); Authentication a =
|
||||
* provider.authenticate(new
|
||||
* UsernamePasswordAuthenticationToken("expireme","password")); PasswordPolicyData ud
|
||||
* = (LdapUserDetailsImpl) a.getPrincipal(); assertTrue(ud.getTimeBeforeExpiration() <
|
||||
* Integer.MAX_VALUE && ud.getTimeBeforeExpiration() > 0); }
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -17,46 +17,53 @@ import java.util.*;
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class PasswordPolicyAwareContextSourceTests {
|
||||
private PasswordPolicyAwareContextSource ctxSource;
|
||||
private final LdapContext ctx = mock(LdapContext.class);
|
||||
private PasswordPolicyAwareContextSource ctxSource;
|
||||
private final LdapContext ctx = mock(LdapContext.class);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
reset(ctx);
|
||||
ctxSource = new PasswordPolicyAwareContextSource("ldap://blah:789/dc=springframework,dc=org") {
|
||||
@Override
|
||||
protected DirContext createContext(Hashtable env) {
|
||||
if ("manager".equals(env.get(Context.SECURITY_PRINCIPAL))) {
|
||||
return ctx;
|
||||
}
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
reset(ctx);
|
||||
ctxSource = new PasswordPolicyAwareContextSource(
|
||||
"ldap://blah:789/dc=springframework,dc=org") {
|
||||
@Override
|
||||
protected DirContext createContext(Hashtable env) {
|
||||
if ("manager".equals(env.get(Context.SECURITY_PRINCIPAL))) {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
ctxSource.setUserDn("manager");
|
||||
ctxSource.setPassword("password");
|
||||
ctxSource.afterPropertiesSet();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
ctxSource.setUserDn("manager");
|
||||
ctxSource.setPassword("password");
|
||||
ctxSource.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextIsReturnedWhenNoControlsAreSetAndReconnectIsSuccessful() throws Exception {
|
||||
assertNotNull(ctxSource.getContext("user", "ignored"));
|
||||
}
|
||||
@Test
|
||||
public void contextIsReturnedWhenNoControlsAreSetAndReconnectIsSuccessful()
|
||||
throws Exception {
|
||||
assertNotNull(ctxSource.getContext("user", "ignored"));
|
||||
}
|
||||
|
||||
@Test(expected=UncategorizedLdapException.class)
|
||||
public void standardExceptionIsPropagatedWhenExceptionRaisedAndNoControlsAreSet() throws Exception {
|
||||
doThrow(new NamingException("some LDAP exception")).when(ctx).reconnect(any(Control[].class));
|
||||
@Test(expected = UncategorizedLdapException.class)
|
||||
public void standardExceptionIsPropagatedWhenExceptionRaisedAndNoControlsAreSet()
|
||||
throws Exception {
|
||||
doThrow(new NamingException("some LDAP exception")).when(ctx).reconnect(
|
||||
any(Control[].class));
|
||||
|
||||
ctxSource.getContext("user", "ignored");
|
||||
}
|
||||
ctxSource.getContext("user", "ignored");
|
||||
}
|
||||
|
||||
@Test(expected=PasswordPolicyException.class)
|
||||
public void lockedPasswordPolicyControlRaisesPasswordPolicyException() throws Exception {
|
||||
when(ctx.getResponseControls()).thenReturn(new Control[] {
|
||||
new PasswordPolicyResponseControl(PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL) });
|
||||
@Test(expected = PasswordPolicyException.class)
|
||||
public void lockedPasswordPolicyControlRaisesPasswordPolicyException()
|
||||
throws Exception {
|
||||
when(ctx.getResponseControls()).thenReturn(
|
||||
new Control[] { new PasswordPolicyResponseControl(
|
||||
PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL) });
|
||||
|
||||
doThrow(new NamingException("locked message")).when(ctx).reconnect(any(Control[].class));
|
||||
doThrow(new NamingException("locked message")).when(ctx).reconnect(
|
||||
any(Control[].class));
|
||||
|
||||
ctxSource.getContext("user", "ignored");
|
||||
}
|
||||
ctxSource.getContext("user", "ignored");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,24 +13,26 @@ import java.util.*;
|
||||
*/
|
||||
public class PasswordPolicyControlFactoryTests {
|
||||
|
||||
@Test
|
||||
public void returnsNullForUnrecognisedOID() throws Exception {
|
||||
PasswordPolicyControlFactory ctrlFactory = new PasswordPolicyControlFactory();
|
||||
Control wrongCtrl = mock(Control.class);
|
||||
@Test
|
||||
public void returnsNullForUnrecognisedOID() throws Exception {
|
||||
PasswordPolicyControlFactory ctrlFactory = new PasswordPolicyControlFactory();
|
||||
Control wrongCtrl = mock(Control.class);
|
||||
|
||||
when(wrongCtrl.getID()).thenReturn("wrongId");
|
||||
assertNull(ctrlFactory.getControlInstance(wrongCtrl));
|
||||
}
|
||||
when(wrongCtrl.getID()).thenReturn("wrongId");
|
||||
assertNull(ctrlFactory.getControlInstance(wrongCtrl));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsControlForCorrectOID() throws Exception {
|
||||
PasswordPolicyControlFactory ctrlFactory = new PasswordPolicyControlFactory();
|
||||
Control control = mock(Control.class);
|
||||
@Test
|
||||
public void returnsControlForCorrectOID() throws Exception {
|
||||
PasswordPolicyControlFactory ctrlFactory = new PasswordPolicyControlFactory();
|
||||
Control control = mock(Control.class);
|
||||
|
||||
when(control.getID()).thenReturn(PasswordPolicyControl.OID);
|
||||
when(control.getEncodedValue()).thenReturn(PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL);
|
||||
Control result = ctrlFactory.getControlInstance(control);
|
||||
assertNotNull(result);
|
||||
assertTrue(Arrays.equals(PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL, result.getEncodedValue()));
|
||||
}
|
||||
when(control.getID()).thenReturn(PasswordPolicyControl.OID);
|
||||
when(control.getEncodedValue()).thenReturn(
|
||||
PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL);
|
||||
Control result = ctrlFactory.getControlInstance(control);
|
||||
assertNotNull(result);
|
||||
assertTrue(Arrays.equals(PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL,
|
||||
result.getEncodedValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,106 +28,113 @@ import java.util.*;
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class PasswordPolicyResponseControlTests {
|
||||
//~ Methods ========================================================================================================
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* Useful method for obtaining data from a server for use in tests
|
||||
*/
|
||||
// public void testAgainstServer() throws Exception {
|
||||
// Hashtable env = new Hashtable();
|
||||
// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
// env.put(Context.PROVIDER_URL, "ldap://gorille:389/");
|
||||
// env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
// env.put(Context.SECURITY_PRINCIPAL, "cn=manager,dc=security,dc=org");
|
||||
// env.put(Context.SECURITY_CREDENTIALS, "security");
|
||||
// env.put(LdapContext.CONTROL_FACTORIES, PasswordPolicyControlFactory.class.getName());
|
||||
//
|
||||
// InitialLdapContext ctx = new InitialLdapContext(env, null);
|
||||
//
|
||||
// Control[] rctls = { new PasswordPolicyControl(false) };
|
||||
//
|
||||
// ctx.setRequestControls(rctls);
|
||||
//
|
||||
// try {
|
||||
// ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, "uid=bob,ou=people,dc=security,dc=org" );
|
||||
// ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, "bobspassword");
|
||||
// Object o = ctx.lookup("");
|
||||
//
|
||||
// System.out.println(o);
|
||||
//
|
||||
// } catch(NamingException ne) {
|
||||
// // Ok.
|
||||
// System.err.println(ne);
|
||||
// }
|
||||
//
|
||||
// PasswordPolicyResponseControl ctrl = getPPolicyResponseCtl(ctx);
|
||||
// System.out.println(ctrl);
|
||||
//
|
||||
// assertNotNull(ctrl);
|
||||
//
|
||||
// //com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
|
||||
// }
|
||||
/**
|
||||
* Useful method for obtaining data from a server for use in tests
|
||||
*/
|
||||
// public void testAgainstServer() throws Exception {
|
||||
// Hashtable env = new Hashtable();
|
||||
// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
// env.put(Context.PROVIDER_URL, "ldap://gorille:389/");
|
||||
// env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
// env.put(Context.SECURITY_PRINCIPAL, "cn=manager,dc=security,dc=org");
|
||||
// env.put(Context.SECURITY_CREDENTIALS, "security");
|
||||
// env.put(LdapContext.CONTROL_FACTORIES,
|
||||
// PasswordPolicyControlFactory.class.getName());
|
||||
//
|
||||
// InitialLdapContext ctx = new InitialLdapContext(env, null);
|
||||
//
|
||||
// Control[] rctls = { new PasswordPolicyControl(false) };
|
||||
//
|
||||
// ctx.setRequestControls(rctls);
|
||||
//
|
||||
// try {
|
||||
// ctx.addToEnvironment(Context.SECURITY_PRINCIPAL,
|
||||
// "uid=bob,ou=people,dc=security,dc=org" );
|
||||
// ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, "bobspassword");
|
||||
// Object o = ctx.lookup("");
|
||||
//
|
||||
// System.out.println(o);
|
||||
//
|
||||
// } catch(NamingException ne) {
|
||||
// // Ok.
|
||||
// System.err.println(ne);
|
||||
// }
|
||||
//
|
||||
// PasswordPolicyResponseControl ctrl = getPPolicyResponseCtl(ctx);
|
||||
// System.out.println(ctrl);
|
||||
//
|
||||
// assertNotNull(ctrl);
|
||||
//
|
||||
// //com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
|
||||
// }
|
||||
|
||||
// private PasswordPolicyResponseControl getPPolicyResponseCtl(InitialLdapContext ctx)
|
||||
// throws NamingException {
|
||||
// Control[] ctrls = ctx.getResponseControls();
|
||||
//
|
||||
// for (int i = 0; ctrls != null && i < ctrls.length; i++) {
|
||||
// if (ctrls[i] instanceof PasswordPolicyResponseControl) {
|
||||
// return (PasswordPolicyResponseControl) ctrls[i];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// private PasswordPolicyResponseControl getPPolicyResponseCtl(InitialLdapContext ctx) throws NamingException {
|
||||
// Control[] ctrls = ctx.getResponseControls();
|
||||
//
|
||||
// for (int i = 0; ctrls != null && i < ctrls.length; i++) {
|
||||
// if (ctrls[i] instanceof PasswordPolicyResponseControl) {
|
||||
// return (PasswordPolicyResponseControl) ctrls[i];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
@Test
|
||||
public void openLDAP33SecondsTillPasswordExpiryCtrlIsParsedCorrectly() {
|
||||
byte[] ctrlBytes = { 0x30, 0x05, (byte) 0xA0, 0x03, (byte) 0xA0, 0x1, 0x21 };
|
||||
|
||||
@Test
|
||||
public void openLDAP33SecondsTillPasswordExpiryCtrlIsParsedCorrectly() {
|
||||
byte[] ctrlBytes = {0x30, 0x05, (byte) 0xA0, 0x03, (byte) 0xA0, 0x1, 0x21};
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
|
||||
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
|
||||
assertTrue(ctrl.hasWarning());
|
||||
assertEquals(33, ctrl.getTimeBeforeExpiration());
|
||||
}
|
||||
|
||||
assertTrue(ctrl.hasWarning());
|
||||
assertEquals(33, ctrl.getTimeBeforeExpiration());
|
||||
}
|
||||
@Test
|
||||
public void openLDAP496GraceLoginsRemainingCtrlIsParsedCorrectly() {
|
||||
byte[] ctrlBytes = { 0x30, 0x06, (byte) 0xA0, 0x04, (byte) 0xA1, 0x02, 0x01,
|
||||
(byte) 0xF0 };
|
||||
|
||||
@Test
|
||||
public void openLDAP496GraceLoginsRemainingCtrlIsParsedCorrectly() {
|
||||
byte[] ctrlBytes = {0x30, 0x06, (byte) 0xA0, 0x04, (byte) 0xA1, 0x02, 0x01, (byte) 0xF0};
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
|
||||
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
|
||||
assertTrue(ctrl.hasWarning());
|
||||
assertEquals(496, ctrl.getGraceLoginsRemaining());
|
||||
}
|
||||
|
||||
assertTrue(ctrl.hasWarning());
|
||||
assertEquals(496, ctrl.getGraceLoginsRemaining());
|
||||
}
|
||||
static final byte[] OPENLDAP_5_LOGINS_REMAINING_CTRL = { 0x30, 0x05, (byte) 0xA0,
|
||||
0x03, (byte) 0xA1, 0x01, 0x05 };
|
||||
|
||||
static final byte[] OPENLDAP_5_LOGINS_REMAINING_CTRL = {0x30, 0x05, (byte) 0xA0, 0x03, (byte) 0xA1, 0x01, 0x05};
|
||||
@Test
|
||||
public void openLDAP5GraceLoginsRemainingCtrlIsParsedCorrectly() {
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(
|
||||
OPENLDAP_5_LOGINS_REMAINING_CTRL);
|
||||
|
||||
@Test
|
||||
public void openLDAP5GraceLoginsRemainingCtrlIsParsedCorrectly() {
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(OPENLDAP_5_LOGINS_REMAINING_CTRL);
|
||||
assertTrue(ctrl.hasWarning());
|
||||
assertEquals(5, ctrl.getGraceLoginsRemaining());
|
||||
}
|
||||
|
||||
assertTrue(ctrl.hasWarning());
|
||||
assertEquals(5, ctrl.getGraceLoginsRemaining());
|
||||
}
|
||||
static final byte[] OPENLDAP_LOCKED_CTRL = { 0x30, 0x03, (byte) 0xA1, 0x01, 0x01 };
|
||||
|
||||
static final byte[] OPENLDAP_LOCKED_CTRL = {0x30, 0x03, (byte) 0xA1, 0x01, 0x01};
|
||||
@Test
|
||||
public void openLDAPAccountLockedCtrlIsParsedCorrectly() {
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(
|
||||
OPENLDAP_LOCKED_CTRL);
|
||||
|
||||
@Test
|
||||
public void openLDAPAccountLockedCtrlIsParsedCorrectly() {
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(OPENLDAP_LOCKED_CTRL);
|
||||
assertTrue(ctrl.hasError() && ctrl.isLocked());
|
||||
assertFalse(ctrl.hasWarning());
|
||||
}
|
||||
|
||||
assertTrue(ctrl.hasError() && ctrl.isLocked());
|
||||
assertFalse(ctrl.hasWarning());
|
||||
}
|
||||
@Test
|
||||
public void openLDAPPasswordExpiredCtrlIsParsedCorrectly() {
|
||||
byte[] ctrlBytes = { 0x30, 0x03, (byte) 0xA1, 0x01, 0x00 };
|
||||
|
||||
@Test
|
||||
public void openLDAPPasswordExpiredCtrlIsParsedCorrectly() {
|
||||
byte[] ctrlBytes = {0x30, 0x03, (byte) 0xA1, 0x01, 0x00};
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
|
||||
|
||||
PasswordPolicyResponseControl ctrl = new PasswordPolicyResponseControl(ctrlBytes);
|
||||
|
||||
assertTrue(ctrl.hasError() && ctrl.isExpired());
|
||||
assertFalse(ctrl.hasWarning());
|
||||
}
|
||||
assertTrue(ctrl.hasError() && ctrl.isExpired());
|
||||
assertFalse(ctrl.hasWarning());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,122 +14,127 @@ import org.springframework.ldap.core.DistinguishedName;
|
||||
*/
|
||||
public class InetOrgPersonTests {
|
||||
|
||||
@Test
|
||||
public void testUsernameIsMappedFromContextUidIfNotSet() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
@Test
|
||||
public void testUsernameIsMappedFromContextUidIfNotSet() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
|
||||
assertEquals("ghengis", p.getUsername());
|
||||
}
|
||||
assertEquals("ghengis", p.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashLookupViaEqualObjectRetrievesOriginal() throws Exception {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p2 = (InetOrgPerson) essence.createUserDetails();
|
||||
Set<InetOrgPerson> set = new HashSet<InetOrgPerson>();
|
||||
set.add(p);
|
||||
assertTrue(set.contains(p2));
|
||||
}
|
||||
@Test
|
||||
public void hashLookupViaEqualObjectRetrievesOriginal() throws Exception {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p2 = (InetOrgPerson) essence.createUserDetails();
|
||||
Set<InetOrgPerson> set = new HashSet<InetOrgPerson>();
|
||||
set.add(p);
|
||||
assertTrue(set.contains(p2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usernameIsDifferentFromContextUidIfSet() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
essence.setUsername("joe");
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
@Test
|
||||
public void usernameIsDifferentFromContextUidIfSet() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
essence.setUsername("joe");
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
|
||||
assertEquals("joe", p.getUsername());
|
||||
assertEquals("ghengis", p.getUid());
|
||||
}
|
||||
assertEquals("joe", p.getUsername());
|
||||
assertEquals("ghengis", p.getUid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributesMapCorrectlyFromContext() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
@Test
|
||||
public void attributesMapCorrectlyFromContext() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
|
||||
assertEquals("HORS1", p.getCarLicense());
|
||||
assertEquals("ghengis@mongolia", p.getMail());
|
||||
assertEquals("Ghengis", p.getGivenName());
|
||||
assertEquals("Khan", p.getSn());
|
||||
assertEquals("Ghengis Khan", p.getCn()[0]);
|
||||
assertEquals("00001", p.getEmployeeNumber());
|
||||
assertEquals("+442075436521", p.getTelephoneNumber());
|
||||
assertEquals("Steppes", p.getHomePostalAddress());
|
||||
assertEquals("+467575436521", p.getHomePhone());
|
||||
assertEquals("Hordes", p.getO());
|
||||
assertEquals("Horde1", p.getOu());
|
||||
assertEquals("On the Move", p.getPostalAddress());
|
||||
assertEquals("Changes Frequently", p.getPostalCode());
|
||||
assertEquals("Yurt 1", p.getRoomNumber());
|
||||
assertEquals("Westward Avenue", p.getStreet());
|
||||
assertEquals("Scary", p.getDescription());
|
||||
assertEquals("Ghengis McCann", p.getDisplayName());
|
||||
assertEquals("G", p.getInitials());
|
||||
}
|
||||
assertEquals("HORS1", p.getCarLicense());
|
||||
assertEquals("ghengis@mongolia", p.getMail());
|
||||
assertEquals("Ghengis", p.getGivenName());
|
||||
assertEquals("Khan", p.getSn());
|
||||
assertEquals("Ghengis Khan", p.getCn()[0]);
|
||||
assertEquals("00001", p.getEmployeeNumber());
|
||||
assertEquals("+442075436521", p.getTelephoneNumber());
|
||||
assertEquals("Steppes", p.getHomePostalAddress());
|
||||
assertEquals("+467575436521", p.getHomePhone());
|
||||
assertEquals("Hordes", p.getO());
|
||||
assertEquals("Horde1", p.getOu());
|
||||
assertEquals("On the Move", p.getPostalAddress());
|
||||
assertEquals("Changes Frequently", p.getPostalCode());
|
||||
assertEquals("Yurt 1", p.getRoomNumber());
|
||||
assertEquals("Westward Avenue", p.getStreet());
|
||||
assertEquals("Scary", p.getDescription());
|
||||
assertEquals("Ghengis McCann", p.getDisplayName());
|
||||
assertEquals("G", p.getInitials());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordIsSetFromContextUserPassword() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
@Test
|
||||
public void testPasswordIsSetFromContextUserPassword() {
|
||||
InetOrgPerson.Essence essence = new InetOrgPerson.Essence(createUserContext());
|
||||
InetOrgPerson p = (InetOrgPerson) essence.createUserDetails();
|
||||
|
||||
assertEquals("pillage", p.getPassword());
|
||||
}
|
||||
assertEquals("pillage", p.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mappingBackToContextMatchesOriginalData() {
|
||||
DirContextAdapter ctx1 = createUserContext();
|
||||
DirContextAdapter ctx2 = new DirContextAdapter();
|
||||
ctx1.setAttributeValues("objectclass", new String[] {"top", "person", "organizationalPerson", "inetOrgPerson"});
|
||||
ctx2.setDn(new DistinguishedName("ignored=ignored"));
|
||||
InetOrgPerson p = (InetOrgPerson) (new InetOrgPerson.Essence(ctx1)).createUserDetails();
|
||||
p.populateContext(ctx2);
|
||||
@Test
|
||||
public void mappingBackToContextMatchesOriginalData() {
|
||||
DirContextAdapter ctx1 = createUserContext();
|
||||
DirContextAdapter ctx2 = new DirContextAdapter();
|
||||
ctx1.setAttributeValues("objectclass", new String[] { "top", "person",
|
||||
"organizationalPerson", "inetOrgPerson" });
|
||||
ctx2.setDn(new DistinguishedName("ignored=ignored"));
|
||||
InetOrgPerson p = (InetOrgPerson) (new InetOrgPerson.Essence(ctx1))
|
||||
.createUserDetails();
|
||||
p.populateContext(ctx2);
|
||||
|
||||
assertEquals(ctx1, ctx2);
|
||||
}
|
||||
assertEquals(ctx1, ctx2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void copyMatchesOriginalData() {
|
||||
DirContextAdapter ctx1 = createUserContext();
|
||||
DirContextAdapter ctx2 = new DirContextAdapter();
|
||||
ctx2.setDn(new DistinguishedName("ignored=ignored"));
|
||||
ctx1.setAttributeValues("objectclass", new String[] {"top", "person", "organizationalPerson", "inetOrgPerson"});
|
||||
InetOrgPerson p = (InetOrgPerson) (new InetOrgPerson.Essence(ctx1)).createUserDetails();
|
||||
InetOrgPerson p2 = (InetOrgPerson) new InetOrgPerson.Essence(p).createUserDetails();
|
||||
p2.populateContext(ctx2);
|
||||
@Test
|
||||
public void copyMatchesOriginalData() {
|
||||
DirContextAdapter ctx1 = createUserContext();
|
||||
DirContextAdapter ctx2 = new DirContextAdapter();
|
||||
ctx2.setDn(new DistinguishedName("ignored=ignored"));
|
||||
ctx1.setAttributeValues("objectclass", new String[] { "top", "person",
|
||||
"organizationalPerson", "inetOrgPerson" });
|
||||
InetOrgPerson p = (InetOrgPerson) (new InetOrgPerson.Essence(ctx1))
|
||||
.createUserDetails();
|
||||
InetOrgPerson p2 = (InetOrgPerson) new InetOrgPerson.Essence(p)
|
||||
.createUserDetails();
|
||||
p2.populateContext(ctx2);
|
||||
|
||||
assertEquals(ctx1, ctx2);
|
||||
}
|
||||
assertEquals(ctx1, ctx2);
|
||||
}
|
||||
|
||||
private DirContextAdapter createUserContext() {
|
||||
DirContextAdapter ctx = new DirContextAdapter();
|
||||
private DirContextAdapter createUserContext() {
|
||||
DirContextAdapter ctx = new DirContextAdapter();
|
||||
|
||||
ctx.setDn(new DistinguishedName("ignored=ignored"));
|
||||
ctx.setAttributeValue("uid", "ghengis");
|
||||
ctx.setAttributeValue("userPassword", "pillage");
|
||||
ctx.setAttributeValue("carLicense", "HORS1");
|
||||
ctx.setAttributeValue("cn", "Ghengis Khan");
|
||||
ctx.setAttributeValue("description", "Scary");
|
||||
ctx.setAttributeValue("destinationIndicator", "West");
|
||||
ctx.setAttributeValue("displayName", "Ghengis McCann");
|
||||
ctx.setAttributeValue("givenName", "Ghengis");
|
||||
ctx.setAttributeValue("homePhone", "+467575436521");
|
||||
ctx.setAttributeValue("initials", "G");
|
||||
ctx.setAttributeValue("employeeNumber", "00001");
|
||||
ctx.setAttributeValue("homePostalAddress", "Steppes");
|
||||
ctx.setAttributeValue("mail", "ghengis@mongolia");
|
||||
ctx.setAttributeValue("mobile", "always");
|
||||
ctx.setAttributeValue("o", "Hordes");
|
||||
ctx.setAttributeValue("ou", "Horde1");
|
||||
ctx.setAttributeValue("postalAddress", "On the Move");
|
||||
ctx.setAttributeValue("postalCode", "Changes Frequently");
|
||||
ctx.setAttributeValue("roomNumber", "Yurt 1");
|
||||
ctx.setAttributeValue("roomNumber", "Yurt 1");
|
||||
ctx.setAttributeValue("sn", "Khan");
|
||||
ctx.setAttributeValue("street", "Westward Avenue");
|
||||
ctx.setAttributeValue("telephoneNumber", "+442075436521");
|
||||
ctx.setDn(new DistinguishedName("ignored=ignored"));
|
||||
ctx.setAttributeValue("uid", "ghengis");
|
||||
ctx.setAttributeValue("userPassword", "pillage");
|
||||
ctx.setAttributeValue("carLicense", "HORS1");
|
||||
ctx.setAttributeValue("cn", "Ghengis Khan");
|
||||
ctx.setAttributeValue("description", "Scary");
|
||||
ctx.setAttributeValue("destinationIndicator", "West");
|
||||
ctx.setAttributeValue("displayName", "Ghengis McCann");
|
||||
ctx.setAttributeValue("givenName", "Ghengis");
|
||||
ctx.setAttributeValue("homePhone", "+467575436521");
|
||||
ctx.setAttributeValue("initials", "G");
|
||||
ctx.setAttributeValue("employeeNumber", "00001");
|
||||
ctx.setAttributeValue("homePostalAddress", "Steppes");
|
||||
ctx.setAttributeValue("mail", "ghengis@mongolia");
|
||||
ctx.setAttributeValue("mobile", "always");
|
||||
ctx.setAttributeValue("o", "Hordes");
|
||||
ctx.setAttributeValue("ou", "Horde1");
|
||||
ctx.setAttributeValue("postalAddress", "On the Move");
|
||||
ctx.setAttributeValue("postalCode", "Changes Frequently");
|
||||
ctx.setAttributeValue("roomNumber", "Yurt 1");
|
||||
ctx.setAttributeValue("roomNumber", "Yurt 1");
|
||||
ctx.setAttributeValue("sn", "Khan");
|
||||
ctx.setAttributeValue("street", "Westward Avenue");
|
||||
ctx.setAttributeValue("telephoneNumber", "+442075436521");
|
||||
|
||||
return ctx;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,38 +17,41 @@ import static org.junit.Assert.assertNotNull;
|
||||
*/
|
||||
public class LdapAuthorityTests {
|
||||
|
||||
public static final String DN = "cn=filip,ou=Users,dc=test,dc=com";
|
||||
LdapAuthority authority;
|
||||
public static final String DN = "cn=filip,ou=Users,dc=test,dc=com";
|
||||
LdapAuthority authority;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Map<String, List<String>> attributes = new HashMap<String, List<String>>();
|
||||
attributes.put(SpringSecurityLdapTemplate.DN_KEY, Arrays.asList(DN));
|
||||
attributes.put("mail", Arrays.asList("filip@ldap.test.org", "filip@ldap.test2.org"));
|
||||
authority = new LdapAuthority("testRole", DN, attributes);
|
||||
}
|
||||
@Before
|
||||
public void setUp() {
|
||||
Map<String, List<String>> attributes = new HashMap<String, List<String>>();
|
||||
attributes.put(SpringSecurityLdapTemplate.DN_KEY, Arrays.asList(DN));
|
||||
attributes.put("mail",
|
||||
Arrays.asList("filip@ldap.test.org", "filip@ldap.test2.org"));
|
||||
authority = new LdapAuthority("testRole", DN, attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDn() throws Exception {
|
||||
assertEquals(DN, authority.getDn());
|
||||
assertNotNull(authority.getAttributeValues(SpringSecurityLdapTemplate.DN_KEY));
|
||||
assertEquals(1, authority.getAttributeValues(SpringSecurityLdapTemplate.DN_KEY).size());
|
||||
assertEquals(DN, authority.getFirstAttributeValue(SpringSecurityLdapTemplate.DN_KEY));
|
||||
}
|
||||
@Test
|
||||
public void testGetDn() throws Exception {
|
||||
assertEquals(DN, authority.getDn());
|
||||
assertNotNull(authority.getAttributeValues(SpringSecurityLdapTemplate.DN_KEY));
|
||||
assertEquals(1, authority.getAttributeValues(SpringSecurityLdapTemplate.DN_KEY)
|
||||
.size());
|
||||
assertEquals(DN,
|
||||
authority.getFirstAttributeValue(SpringSecurityLdapTemplate.DN_KEY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributes() throws Exception {
|
||||
assertNotNull(authority.getAttributes());
|
||||
assertNotNull(authority.getAttributeValues("mail"));
|
||||
assertEquals(2, authority.getAttributeValues("mail").size());
|
||||
assertEquals("filip@ldap.test.org", authority.getFirstAttributeValue("mail"));
|
||||
assertEquals("filip@ldap.test.org", authority.getAttributeValues("mail").get(0));
|
||||
assertEquals("filip@ldap.test2.org", authority.getAttributeValues("mail").get(1));
|
||||
}
|
||||
@Test
|
||||
public void testGetAttributes() throws Exception {
|
||||
assertNotNull(authority.getAttributes());
|
||||
assertNotNull(authority.getAttributeValues("mail"));
|
||||
assertEquals(2, authority.getAttributeValues("mail").size());
|
||||
assertEquals("filip@ldap.test.org", authority.getFirstAttributeValue("mail"));
|
||||
assertEquals("filip@ldap.test.org", authority.getAttributeValues("mail").get(0));
|
||||
assertEquals("filip@ldap.test2.org", authority.getAttributeValues("mail").get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAuthority() throws Exception {
|
||||
assertNotNull(authority.getAuthority());
|
||||
assertEquals("testRole", authority.getAuthority());
|
||||
}
|
||||
@Test
|
||||
public void testGetAuthority() throws Exception {
|
||||
assertNotNull(authority.getAuthority());
|
||||
assertEquals("testRole", authority.getAuthority());
|
||||
}
|
||||
}
|
||||
@@ -31,55 +31,61 @@ import org.springframework.security.core.authority.AuthorityUtils;
|
||||
*/
|
||||
public class LdapUserDetailsMapperTests extends TestCase {
|
||||
|
||||
public void testMultipleRoleAttributeValuesAreMappedToAuthorities() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
mapper.setConvertToUpperCase(false);
|
||||
mapper.setRolePrefix("");
|
||||
public void testMultipleRoleAttributeValuesAreMappedToAuthorities() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
mapper.setConvertToUpperCase(false);
|
||||
mapper.setRolePrefix("");
|
||||
|
||||
mapper.setRoleAttributes(new String[] {"userRole"});
|
||||
mapper.setRoleAttributes(new String[] { "userRole" });
|
||||
|
||||
DirContextAdapter ctx = new DirContextAdapter();
|
||||
DirContextAdapter ctx = new DirContextAdapter();
|
||||
|
||||
ctx.setAttributeValues("userRole", new String[] {"X", "Y", "Z"});
|
||||
ctx.setAttributeValue("uid", "ani");
|
||||
ctx.setAttributeValues("userRole", new String[] { "X", "Y", "Z" });
|
||||
ctx.setAttributeValue("uid", "ani");
|
||||
|
||||
LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx, "ani", AuthorityUtils.NO_AUTHORITIES);
|
||||
LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx,
|
||||
"ani", AuthorityUtils.NO_AUTHORITIES);
|
||||
|
||||
assertEquals(3, user.getAuthorities().size());
|
||||
}
|
||||
assertEquals(3, user.getAuthorities().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* SEC-303. Non-retrieved role attribute causes NullPointerException
|
||||
*/
|
||||
public void testNonRetrievedRoleAttributeIsIgnored() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
/**
|
||||
* SEC-303. Non-retrieved role attribute causes NullPointerException
|
||||
*/
|
||||
public void testNonRetrievedRoleAttributeIsIgnored() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
|
||||
mapper.setRoleAttributes(new String[] {"userRole", "nonRetrievedAttribute"});
|
||||
mapper.setRoleAttributes(new String[] { "userRole", "nonRetrievedAttribute" });
|
||||
|
||||
BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("userRole", "x"));
|
||||
BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("userRole", "x"));
|
||||
|
||||
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName"));
|
||||
ctx.setAttributeValue("uid", "ani");
|
||||
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName(
|
||||
"cn=someName"));
|
||||
ctx.setAttributeValue("uid", "ani");
|
||||
|
||||
LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx, "ani", AuthorityUtils.NO_AUTHORITIES);
|
||||
LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx,
|
||||
"ani", AuthorityUtils.NO_AUTHORITIES);
|
||||
|
||||
assertEquals(1, user.getAuthorities().size());
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains("ROLE_X"));
|
||||
}
|
||||
assertEquals(1, user.getAuthorities().size());
|
||||
assertTrue(AuthorityUtils.authorityListToSet(user.getAuthorities()).contains(
|
||||
"ROLE_X"));
|
||||
}
|
||||
|
||||
public void testPasswordAttributeIsMappedCorrectly() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
public void testPasswordAttributeIsMappedCorrectly() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
|
||||
mapper.setPasswordAttributeName("myappsPassword");
|
||||
BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("myappsPassword", "mypassword".getBytes()));
|
||||
mapper.setPasswordAttributeName("myappsPassword");
|
||||
BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("myappsPassword", "mypassword".getBytes()));
|
||||
|
||||
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName"));
|
||||
ctx.setAttributeValue("uid", "ani");
|
||||
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName(
|
||||
"cn=someName"));
|
||||
ctx.setAttributeValue("uid", "ani");
|
||||
|
||||
LdapUserDetails user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx, "ani", AuthorityUtils.NO_AUTHORITIES);
|
||||
LdapUserDetails user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx,
|
||||
"ani", AuthorityUtils.NO_AUTHORITIES);
|
||||
|
||||
assertEquals("mypassword", user.getPassword());
|
||||
}
|
||||
assertEquals("mypassword", user.getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,43 +22,48 @@ import org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopul
|
||||
*/
|
||||
public class LdapUserDetailsServiceTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullSearchObject() {
|
||||
new LdapUserDetailsService(null, new NullLdapAuthoritiesPopulator());
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullSearchObject() {
|
||||
new LdapUserDetailsService(null, new NullLdapAuthoritiesPopulator());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullAuthoritiesPopulator() {
|
||||
new LdapUserDetailsService(new MockUserSearch(), null);
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullAuthoritiesPopulator() {
|
||||
new LdapUserDetailsService(new MockUserSearch(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctAuthoritiesAreReturned() {
|
||||
DirContextAdapter userData = new DirContextAdapter(new DistinguishedName("uid=joe"));
|
||||
@Test
|
||||
public void correctAuthoritiesAreReturned() {
|
||||
DirContextAdapter userData = new DirContextAdapter(new DistinguishedName(
|
||||
"uid=joe"));
|
||||
|
||||
LdapUserDetailsService service =
|
||||
new LdapUserDetailsService(new MockUserSearch(userData), new MockAuthoritiesPopulator());
|
||||
service.setUserDetailsMapper(new LdapUserDetailsMapper());
|
||||
LdapUserDetailsService service = new LdapUserDetailsService(new MockUserSearch(
|
||||
userData), new MockAuthoritiesPopulator());
|
||||
service.setUserDetailsMapper(new LdapUserDetailsMapper());
|
||||
|
||||
UserDetails user = service.loadUserByUsername("doesntmatterwegetjoeanyway");
|
||||
UserDetails user = service.loadUserByUsername("doesntmatterwegetjoeanyway");
|
||||
|
||||
Set<String> authorities = AuthorityUtils.authorityListToSet(user.getAuthorities());
|
||||
assertEquals(1, authorities.size());
|
||||
assertTrue(authorities.contains("ROLE_FROM_POPULATOR"));
|
||||
}
|
||||
Set<String> authorities = AuthorityUtils
|
||||
.authorityListToSet(user.getAuthorities());
|
||||
assertEquals(1, authorities.size());
|
||||
assertTrue(authorities.contains("ROLE_FROM_POPULATOR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullPopulatorConstructorReturnsEmptyAuthoritiesList() throws Exception {
|
||||
DirContextAdapter userData = new DirContextAdapter(new DistinguishedName("uid=joe"));
|
||||
@Test
|
||||
public void nullPopulatorConstructorReturnsEmptyAuthoritiesList() throws Exception {
|
||||
DirContextAdapter userData = new DirContextAdapter(new DistinguishedName(
|
||||
"uid=joe"));
|
||||
|
||||
LdapUserDetailsService service = new LdapUserDetailsService(new MockUserSearch(userData));
|
||||
UserDetails user = service.loadUserByUsername("doesntmatterwegetjoeanyway");
|
||||
assertEquals(0, user.getAuthorities().size());
|
||||
}
|
||||
LdapUserDetailsService service = new LdapUserDetailsService(new MockUserSearch(
|
||||
userData));
|
||||
UserDetails user = service.loadUserByUsername("doesntmatterwegetjoeanyway");
|
||||
assertEquals(0, user.getAuthorities().size());
|
||||
}
|
||||
|
||||
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||
public Collection<GrantedAuthority> getGrantedAuthorities(DirContextOperations userCtx, String username) {
|
||||
return AuthorityUtils.createAuthorityList("ROLE_FROM_POPULATOR");
|
||||
}
|
||||
}
|
||||
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||
public Collection<GrantedAuthority> getGrantedAuthorities(
|
||||
DirContextOperations userCtx, String username) {
|
||||
return AuthorityUtils.createAuthorityList("ROLE_FROM_POPULATOR");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,18 +19,20 @@ import org.springframework.security.ldap.authentication.UserDetailsServiceLdapAu
|
||||
*/
|
||||
public class UserDetailsServiceLdapAuthoritiesPopulatorTests {
|
||||
|
||||
@Test
|
||||
public void delegationToUserDetailsServiceReturnsCorrectRoles() throws Exception {
|
||||
UserDetailsService uds = mock(UserDetailsService.class);
|
||||
UserDetails user = mock(UserDetails.class);
|
||||
when(uds.loadUserByUsername("joe")).thenReturn(user);
|
||||
List authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
|
||||
when(user.getAuthorities()).thenReturn(authorities);
|
||||
@Test
|
||||
public void delegationToUserDetailsServiceReturnsCorrectRoles() throws Exception {
|
||||
UserDetailsService uds = mock(UserDetailsService.class);
|
||||
UserDetails user = mock(UserDetails.class);
|
||||
when(uds.loadUserByUsername("joe")).thenReturn(user);
|
||||
List authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
|
||||
when(user.getAuthorities()).thenReturn(authorities);
|
||||
|
||||
UserDetailsServiceLdapAuthoritiesPopulator populator = new UserDetailsServiceLdapAuthoritiesPopulator(uds);
|
||||
Collection<? extends GrantedAuthority> auths = populator.getGrantedAuthorities(new DirContextAdapter(), "joe");
|
||||
UserDetailsServiceLdapAuthoritiesPopulator populator = new UserDetailsServiceLdapAuthoritiesPopulator(
|
||||
uds);
|
||||
Collection<? extends GrantedAuthority> auths = populator.getGrantedAuthorities(
|
||||
new DirContextAdapter(), "joe");
|
||||
|
||||
assertEquals(1, auths.size());
|
||||
assertTrue(AuthorityUtils.authorityListToSet(auths).contains("ROLE_USER"));
|
||||
}
|
||||
assertEquals(1, auths.size());
|
||||
assertTrue(AuthorityUtils.authorityListToSet(auths).contains("ROLE_USER"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user