소스 검색

ActiveDirectoryLdapAuthenticationProvider custom environment

This change allows to inject custom environment properties for directory
context initialization.

Fixes: gh-2312
Yuri Konotopov 7 년 전
부모
커밋
669b0ba583

+ 16 - 1
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<String, Object> 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<String, String> env = new Hashtable<>();
+		Hashtable<String, Object> 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<String, Object> 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);

+ 25 - 0
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<String, Object>());
+	}
+
+	@Test
+	public void contextEnvironmentPropertiesUsed() throws Exception {
+		Hashtable<String, Object> 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