SEC-2071: ActiveDirectoryLdapAuthenticationProvider custom rootDn

Allow to provide a root DN different from the domain
This commit is contained in:
Henri Tremblay 2014-09-09 12:34:37 -04:00 committed by Rob Winch
parent 6fd45df1e4
commit fbb902c9b5
2 changed files with 44 additions and 20 deletions

View File

@ -102,6 +102,18 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
// Only used to allow tests to substitute a mock LdapContext
ContextFactory contextFactory = new ContextFactory();
/**
* @param domain the domain name (may be null or empty)
* @param url an LDAP url (or multiple URLs)
* @param rootDn the root DN (may be null or empty)
*/
public ActiveDirectoryLdapAuthenticationProvider(String rootDn, String domain, String url) {
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null;
this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase() : null;
this.url = url;
}
/**
* @param domain the domain name (may be null or empty)
* @param url an LDAP url (or multiple URLs)

View File

@ -73,26 +73,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
@Test
public void successfulAuthenticationProducesExpectedAuthorities() throws Exception {
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), 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());
checkAuthentication("dc=mydomain,dc=eu", provider);
}
// SEC-1915
@ -331,6 +312,13 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
provider.authenticate(joe);
}
@Test
public void rootDnProvidedSeparatelyFromDomainAlsoWorks() throws Exception {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("dc=ad,dc=eu,dc=mydomain", "mydomain.eu", "ldap://192.168.1.200/");
checkAuthentication("dc=ad,dc=eu,dc=mydomain", provider);
}
ContextFactory createContextFactoryThrowing(final NamingException e) {
return new ContextFactory() {
@Override
@ -350,6 +338,30 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
};
}
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;