From 669b0ba5837d1eab7e8cad0293b79bf5589bc63d Mon Sep 17 00:00:00 2001 From: Yuri Konotopov Date: Thu, 16 Aug 2018 20:18:27 +0400 Subject: [PATCH] ActiveDirectoryLdapAuthenticationProvider custom environment This change allows to inject custom environment properties for directory context initialization. Fixes: gh-2312 --- ...veDirectoryLdapAuthenticationProvider.java | 17 ++++++++++++- ...ectoryLdapAuthenticationProviderTests.java | 25 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) 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 826896a146..ff5af7840c 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 @@ -107,6 +107,7 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends private final String url; private boolean convertSubErrorCodesToExceptions; private String searchFilter = "(&(objectClass=user)(userPrincipalName={0}))"; + private Hashtable contextEnvironmentProperties = null; // Only used to allow tests to substitute a mock LdapContext ContextFactory contextFactory = new ContextFactory(); @@ -190,7 +191,7 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends // TODO. add DNS lookup based on domain final String bindUrl = url; - Hashtable env = new Hashtable<>(); + Hashtable env = new Hashtable<>(); env.put(Context.SECURITY_AUTHENTICATION, "simple"); String bindPrincipal = createBindPrincipal(username); env.put(Context.SECURITY_PRINCIPAL, bindPrincipal); @@ -199,6 +200,10 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.OBJECT_FACTORIES, DefaultDirObjectFactory.class.getName()); + if(contextEnvironmentProperties != null) { + env.putAll(contextEnvironmentProperties); + } + try { return contextFactory.createContext(env); } @@ -398,6 +403,16 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends this.searchFilter = searchFilter; } + /** + * Allows a custom environment properties to be used to create initial LDAP context. + * + * @param contextFactory + */ + public void setContextEnvironmentProperties(Hashtable environment) { + Assert.notEmpty(environment, "environment must not be empty"); + this.contextEnvironmentProperties = new Hashtable<>(environment); + } + static class ContextFactory { DirContext createContext(Hashtable env) throws NamingException { return new InitialLdapContext(env, null); 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 2290a76fc7..f2aad0bf23 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 @@ -393,6 +393,31 @@ public class ActiveDirectoryLdapAuthenticationProviderTests { } + @Test(expected = IllegalArgumentException.class) + public void setContextEnvironmentPropertiesNull() { + provider.setContextEnvironmentProperties(null); + } + + @Test(expected = IllegalArgumentException.class) + public void setContextEnvironmentPropertiesEmpty() { + provider.setContextEnvironmentProperties(new Hashtable()); + } + + @Test + public void contextEnvironmentPropertiesUsed() throws Exception { + Hashtable env = new Hashtable<>(); + + env.put("java.naming.ldap.factory.socket", "unknown.package.NonExistingSocketFactory"); + provider.setContextEnvironmentProperties(env); + + try { + provider.authenticate(joe); + } + catch (org.springframework.ldap.CommunicationException expected) { + assertThat(expected.getCause()).isNotInstanceOf(ClassNotFoundException.class); + } + } + ContextFactory createContextFactoryThrowing(final NamingException e) { return new ContextFactory() { @Override