如何在Spring Boot中配置多LDAP实例,实现分服务绑定不同LDAP Context
Got it, let's walk through how to configure two distinct LDAP connections in Spring, where each service uses its own dedicated LDAP context. This ensures Service 1 and Service 2 don't interfere with each other's LDAP operations.
Step 1: Create Separate LDAP Configuration Classes
We'll make two @Configuration classes, each responsible for one LDAP server's setup. The key here is to give each bean a unique name using @Bean("beanName") so we can distinguish them later.
LDAP Config 1
@Configuration public class LdapConfig1 { @Value("${ldap1.url}") private String ldapUrl; @Value("${ldap1.base-dn}") private String baseDn; @Value("${ldap1.bind-username}") private String bindUsername; @Value("${ldap1.bind-password}") private String bindPassword; @Bean("ldapContextSource1") public LdapContextSource ldapContextSource1() { LdapContextSource contextSource = new LdapContextSource(); contextSource.setUrl(ldapUrl); contextSource.setBase(baseDn); contextSource.setUserDn(bindUsername); contextSource.setPassword(bindPassword); // Optional: Add pool settings or other context configurations here return contextSource; } @Bean("ldapTemplate1") public LdapTemplate ldapTemplate1(@Qualifier("ldapContextSource1") LdapContextSource contextSource) { LdapTemplate ldapTemplate = new LdapTemplate(contextSource); ldapTemplate.setIgnorePartialResultException(true); // Common fix for AD partial results return ldapTemplate; } }
LDAP Config 2
Nearly identical to the first, just with unique property keys and bean names:
@Configuration public class LdapConfig2 { @Value("${ldap2.url}") private String ldapUrl; @Value("${ldap2.base-dn}") private String baseDn; @Value("${ldap2.bind-username}") private String bindUsername; @Value("${ldap2.bind-password}") private String bindPassword; @Bean("ldapContextSource2") public LdapContextSource ldapContextSource2() { LdapContextSource contextSource = new LdapContextSource(); contextSource.setUrl(ldapUrl); contextSource.setBase(baseDn); contextSource.setUserDn(bindUsername); contextSource.setPassword(bindPassword); return contextSource; } @Bean("ldapTemplate2") public LdapTemplate ldapTemplate2(@Qualifier("ldapContextSource2") LdapContextSource contextSource) { LdapTemplate ldapTemplate = new LdapTemplate(contextSource); ldapTemplate.setIgnorePartialResultException(true); return ldapTemplate; } }
Step 2: Inject the Correct Beans into Your Services
In each service, use @Qualifier to specify which LDAP template (or context source) you want to inject. This tells Spring exactly which connection to wire up.
Service 1 (Uses LDAP Config 1)
@Service public class LdapService1 { private final LdapTemplate ldapTemplate; // Constructor injection with @Qualifier to target the first LDAP template public LdapService1(@Qualifier("ldapTemplate1") LdapTemplate ldapTemplate) { this.ldapTemplate = ldapTemplate; } // Example operation: Search for users by common name public List<String> findUsersByCommonName(String cn) { String filter = "(cn=" + cn + ")"; return ldapTemplate.search( "", // Uses base DN from Config 1 filter, (AttributesMapper<String>) attrs -> (String) attrs.get("cn").get() ); } }
Service 2 (Uses LDAP Config 2)
@Service public class LdapService2 { private final LdapTemplate ldapTemplate; public LdapService2(@Qualifier("ldapTemplate2") LdapTemplate ldapTemplate) { this.ldapTemplate = ldapTemplate; } // Example operation: Fetch user email by UID public String getUserEmail(String uid) { String filter = "(uid=" + uid + ")"; return ldapTemplate.searchForObject( "", // Uses base DN from Config 2 filter, (AttributesMapper<String>) attrs -> (String) attrs.get("mail").get() ); } }
Step 3: Add Configuration Properties
Populate your application.properties with the two LDAP server details:
# LDAP Server 1 Configuration ldap1.url=ldap://ldap-server-1:389 ldap1.base-dn=dc=example,dc=com ldap1.bind-username=cn=admin,dc=example,dc=com ldap1.bind-password=admin-pass-123 # LDAP Server 2 Configuration ldap2.url=ldap://ldap-server-2:389 ldap2.base-dn=dc=test,dc=org ldap2.bind-username=cn=admin,dc=test,dc=org ldap2.bind-password=test-pass-456
Key Notes
- Isolated Contexts: Each
LdapContextSourceis a separate bean, so their connection pools, authentication details, and settings are completely independent. - Qualifier is Non-Negotiable: Without
@Qualifier, Spring will throw an error when multiple beans of the same type exist. - Direct Context Access: If you need to work directly with
LdapContextSourceinstead ofLdapTemplate, inject it the same way using@Qualifier("ldapContextSource1").
内容的提问来源于stack exchange,提问作者Ahmed

