浏览代码

SEC-2071: ActiveDirectoryLdapAuthenticationProvider custom rootDn

Allow to provide a root DN different from the domain
Henri Tremblay 11 年之前
父节点
当前提交
fbb902c9b5

+ 12 - 0
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)

+ 32 - 20
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<SearchResult> {
         private SearchResult sr;