From fbb902c9b52f9b42b11028ada357f7bb2401be95 Mon Sep 17 00:00:00 2001 From: Henri Tremblay Date: Tue, 9 Sep 2014 12:34:37 -0400 Subject: [PATCH] SEC-2071: ActiveDirectoryLdapAuthenticationProvider custom rootDn Allow to provide a root DN different from the domain --- ...veDirectoryLdapAuthenticationProvider.java | 12 +++++ ...ectoryLdapAuthenticationProviderTests.java | 52 ++++++++++++------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java b/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java index 6a26c2a896..7612873f0e 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java +++ b/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java @@ -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) diff --git a/ldap/src/test/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProviderTests.java b/ldap/src/test/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProviderTests.java index 11935f28ae..61b77732f9 100644 --- a/ldap/src/test/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProviderTests.java +++ b/ldap/src/test/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProviderTests.java @@ -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 { private SearchResult sr;