具有 Spring 个 LDAP 存储库的多个 LDAP 存储库
Multiple LDAP repositories with Spring LDAP Repository
我想用 Spring LDAP 设置多个 LDAP 存储库。我的目标是同时在所有存储库中创建或更新对象。
我使用 LdapRepository Spring 接口,我认为目前还不可能。
我想知道我是否可以创建自己的 LdapRepository 扩展 Spring,但我不知道如何开始。
这是我的配置:
@Configuration
@EnableLdapRepositories("com.xxx.repository.ldap")
@PropertySource("classpath:ldap.properties")
public class LdapConfiguration {
@Autowired
Environment ldapProperties;
@Bean
public LdapContextSourceCustom contextSourceTarget() {
LdapContextSourceCustom ldapContextSource = new LdapContextSourceCustom();
ldapContextSource.setUrl(ldapProperties.getProperty("ldap.url"));
ldapContextSource.setBase(ldapProperties.getProperty("ldap.base"));
ldapContextSource.setUserDn(ldapProperties.getProperty("ldap.userDn"));
ldapContextSource.setPassword(ldapProperties.getProperty("ldap.password"));
ldapContextSource.setKeyStoreFile(ldapProperties.getProperty("ldap.truststore"));
return ldapContextSource;
}
@Bean
public LdapTemplate ldapTemplate(){
return new LdapTemplate(contextSourceTarget());
}
}
为了完整起见,一个存储库:
public interface LdapUserRepository extends LdapRepository<LdapUser> {
}
知道怎么做吗?
在此先感谢您的帮助。
1) 可以指定多个 LDAP 存储库配置。请看下面的例子。 [注意:这取决于spring-引导库]
@Configuration
@EnableLdapRepositories("com.xxx.repository.ldap")
@EnableConfigurationProperties(LdapProperties.class)
public class LdapConfiguration {
@Autowired
private Environment environment;
@Bean(name="contextSource1")
public LdapContextSource contextSourceTarget(LdapProperties ldapProperties) {
LdapContextSource source = new LdapContextSource();
source.setUserDn(this.properties.getUsername());
source.setPassword(this.properties.getPassword());
source.setBase(this.properties.getBase());
source.setUrls(this.properties.determineUrls(this.environment));
source.setBaseEnvironmentProperties(Collections.<String,Object>unmodifiableMap(this.properties.getBaseEnvironment()));
return source;
}
@Bean
public LdapTemplate ldapTemplate(@Qualifier("contextSource1") LdapContextSource contextSource){
return new LdapTemplate(contextSource);
}
}
可以使用application.properties
中的spring.ldap
前缀来配置上面的LdapConfiguration
。您可以通过查看 https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapProperties.java.
查看可用属性
@Configuration
@EnableLdapRepositories(basePackages="com.yyy.repository.ldap", ldapTemplateRef="ldapTemplate2")
public class LdapConfiguration2 {
@Autowired
private Environment environment;
@Bean(name="ldapProperties2")
@ConfigurationProperties(prefix="spring.ldap2")
public LdapProperties ldapProperties() {
return new LdapProperties();
}
@Bean(name="contextSource2")
public LdapContextSource contextSourceTarget(@Qualifier("ldapProperties2") LdapProperties ldapProperties) {
LdapContextSource source = new LdapContextSource();
source.setUserDn(this.properties.getUsername());
source.setPassword(this.properties.getPassword());
source.setBase(this.properties.getBase());
source.setUrls(this.properties.determineUrls(this.environment));
source.setBaseEnvironmentProperties(Collections.<String,Object>unmodifiableMap(this.properties.getBaseEnvironment()));
return source;
}
@Bean(name="ldapTemplate2")
public LdapTemplate ldapTemplate(@Qualifier("contextSource2") LdapContextSource contextSource){
return new LdapTemplate(contextSource);
}
}
LdapConfiguration2
将由application.properties
中的spring.ldap2
前缀配置。
2) 我不认为扩展存储库是解决方案。我建议创建一个 @Service
方法来遍历您的存储库并应用更新。我将在下面提供两种方法。
示例 1)
@Service
public class UpdateRepositories {
public void updateAllRepositories(LdapUserRepository userRepository1, LdapUserRepository userRepository2) {
// apply updates to userRepository1 and userRepository2
}
}
示例 2)
@Service
public class UpdateRepositories {
public void updateAllRepositories(ApplicationContext appContext) {
Map<String, LdapRepository> ldapRepositories = appContext.getBeansofType(LdapRepository.class)
// iterate through map and apply updates
}
}
我还没有编译这段代码,所以如果有什么地方不对或者您需要额外的指导,请告诉我。
我不知道我是否理解正确,但这是我们所做的:
全局配置class
@Bean("odm")
public ObjectDirectoryMapper odm() {
return new DefaultObjectDirectoryMapper();
};
第一次 LDAP 配置class
@Configuration
@PropertySource("classpath:ldap-one.properties")
public class LdapOneConfiguration {
@Autowired
Environment ldapProperties;
@Bean(name = "contextSourceOne")
public LdapContextSourceCustom contextSourceLdapOneTarget() {
LdapContextSourceCustom ldapContextSource = new LdapContextSourceCustom();
ldapContextSource.setUrl(ldapProperties.getProperty("ldap-one.url"));
ldapContextSource.setBase(ldapProperties.getProperty("ldap-one.base"));
ldapContextSource.setUserDn(ldapProperties.getProperty("ldap-one.userDn"));
ldapContextSource.setPassword(ldapProperties.getProperty("ldap-one.password"));
ldapContextSource.setKeyStoreFile(ldapProperties.getProperty("ldap-one.truststore"));
return ldapContextSource;
}
@Bean(name = "ldapTemplateOne")
public LdapTemplate ldapOneTemplate(@Qualifier("contextSourceOne") LdapContextSourceCustom contextSource) {
return new LdapTemplate(contextSource);
}
@Bean(name = "ldapUserRepoOne")
public LdapUserRepository ldapUserRepositoryOne(@Qualifier("ldapTemplateOne") LdapTemplate ldapTemplate,
@Qualifier("odm") ObjectDirectoryMapper odm) {
return new LdapUserRepository(ldapTemplate, odm);
}
@Bean(name = "ldapFamilyRepoOne")
public LdapFamilyRepository ldapFamilyRepositoryOne(@Qualifier("ldapTemplateOne") LdapTemplate ldapTemplate,
@Qualifier("odm") ObjectDirectoryMapper odm) {
return new LdapFamilyRepository(ldapTemplate, odm);
}
}
第二个 LDAP 配置class
@Configuration
@PropertySource("classpath:ldap-two.properties")
public class LdapTwoConfiguration {
@Autowired
Environment ldapProperties;
@Bean(name = "contextSourceTwo")
public LdapContextSourceCustom contextSourceLdapTwoTarget() {
LdapContextSourceCustom ldapContextSource = new LdapContextSourceCustom();
ldapContextSource.setUrl(ldapProperties.getProperty("ldap-two.url"));
ldapContextSource.setBase(ldapProperties.getProperty("ldap-two.base"));
ldapContextSource.setUserDn(ldapProperties.getProperty("ldap-two.userDn"));
ldapContextSource.setPassword(ldapProperties.getProperty("ldap-two.password"));
ldapContextSource.setKeyStoreFile(ldapProperties.getProperty("ldap-two.truststore"));
return ldapContextSource;
}
@Bean(name = "ldapTemplateTwo")
public LdapTemplate ldapTwoTemplate(@Qualifier("contextSourceTwo") LdapContextSourceCustom contextSource) {
return new LdapTemplate(contextSource);
}
@Bean(name = "ldapUserRepoTwo")
public LdapUserRepository ldapUserRepositoryTwo(@Qualifier("ldapTemplateTwo") LdapTemplate ldapTemplate,
@Qualifier("odm") ObjectDirectoryMapper odm) {
return new LdapUserRepository(ldapTemplate, odm);
}
@Bean(name = "ldapFamilyRepoTwo")
public LdapFamilyRepository ldapFamilyRepositoryTwo(@Qualifier("ldapTemplateTwo") LdapTemplate ldapTemplate,
@Qualifier("odm") ObjectDirectoryMapper odm) {
return new LdapFamilyRepository(ldapTemplate, odm);
}
}
Ldap 用户存储库
public class LdapUserRepository extends SimpleLdapRepository<LdapUser> {
public LdapUserRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm) {
super(ldapOperations, odm, LdapUser.class);
}
}
LdapFamily 存储库
public class LdapFamilyRepository extends SimpleLdapRepository<LdapFamily> {
public LdapFamilyRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm) {
super(ldapOperations, odm, LdapFamily.class);
}
}
LdapUser 服务(与 LdapFamily 服务相同)
@Service
public class LdapUserServiceImpl implements LdapUserService {
@Autowired
private ApplicationContext appContext;
private LdapUserRepository uniqueLdapUserRepo;
private List<LdapUserRepository> ldapUserRepoList;
@PostConstruct
private void setUniqueRepo() {
uniqueLdapUserRepo = appContext.getBeansOfType(LdapUserRepository.class).values().iterator().next();
ldapUserRepoList = new ArrayList<>(appContext.getBeansOfType(LdapUserRepository.class).values());
}
@Override
public LdapUser getUser(String uid) {
return uniqueLdapUserRepo.findOne(query().where("uid").is(uid));
}
@Override
public void saveUser(LdapUser user) {
for(LdapUserRepository repo: ldapUserRepoList){
repo.save(user);
}
}
}
我们删除了 LDAP 存储库的自动配置:
@EnableLdapRepositories(basePackages = "com.afklm.paul.repository.ldap", ldapTemplateRef = "ldapTwoTemplate")
感谢 ryan2049 的帮助。
现在实际上有一个更简单的方法:
创建多个配置,用 @EnableLdapRepositories 注释并具有相应的属性
创建第一个配置
@Configuration
@EnableLdapRepositories(basePackages = "first.ldap.package.repository.**", ldapTemplateRef = "firstLdapTemplate")
public class FirstLDAPConfig {
....detail
@Bean("firstLdapTemplate")
public LdapTemplate firstLdapTemplate() {
...template creation
}
}
创建第二个配置
@Configuration
@EnableLdapRepositories(basePackages = "second.ldap.package.repository.**", ldapTemplateRef = "secondLdapTemplate")
public class SecondLDAPConfig {
....detail
@Bean("secondLdapTemplate")
public LdapTemplate secondLdapTemplate() {
...template creation
}
}
每个配置都应该处理它自己的 contextSource
那么只有 EnableLdapRepositories 注释中的指定存储库才会使用该特定的 ContextSource 和 LdapTemplate
我想用 Spring LDAP 设置多个 LDAP 存储库。我的目标是同时在所有存储库中创建或更新对象。
我使用 LdapRepository Spring 接口,我认为目前还不可能。
我想知道我是否可以创建自己的 LdapRepository 扩展 Spring,但我不知道如何开始。
这是我的配置:
@Configuration
@EnableLdapRepositories("com.xxx.repository.ldap")
@PropertySource("classpath:ldap.properties")
public class LdapConfiguration {
@Autowired
Environment ldapProperties;
@Bean
public LdapContextSourceCustom contextSourceTarget() {
LdapContextSourceCustom ldapContextSource = new LdapContextSourceCustom();
ldapContextSource.setUrl(ldapProperties.getProperty("ldap.url"));
ldapContextSource.setBase(ldapProperties.getProperty("ldap.base"));
ldapContextSource.setUserDn(ldapProperties.getProperty("ldap.userDn"));
ldapContextSource.setPassword(ldapProperties.getProperty("ldap.password"));
ldapContextSource.setKeyStoreFile(ldapProperties.getProperty("ldap.truststore"));
return ldapContextSource;
}
@Bean
public LdapTemplate ldapTemplate(){
return new LdapTemplate(contextSourceTarget());
}
}
为了完整起见,一个存储库:
public interface LdapUserRepository extends LdapRepository<LdapUser> {
}
知道怎么做吗?
在此先感谢您的帮助。
1) 可以指定多个 LDAP 存储库配置。请看下面的例子。 [注意:这取决于spring-引导库]
@Configuration
@EnableLdapRepositories("com.xxx.repository.ldap")
@EnableConfigurationProperties(LdapProperties.class)
public class LdapConfiguration {
@Autowired
private Environment environment;
@Bean(name="contextSource1")
public LdapContextSource contextSourceTarget(LdapProperties ldapProperties) {
LdapContextSource source = new LdapContextSource();
source.setUserDn(this.properties.getUsername());
source.setPassword(this.properties.getPassword());
source.setBase(this.properties.getBase());
source.setUrls(this.properties.determineUrls(this.environment));
source.setBaseEnvironmentProperties(Collections.<String,Object>unmodifiableMap(this.properties.getBaseEnvironment()));
return source;
}
@Bean
public LdapTemplate ldapTemplate(@Qualifier("contextSource1") LdapContextSource contextSource){
return new LdapTemplate(contextSource);
}
}
可以使用application.properties
中的spring.ldap
前缀来配置上面的LdapConfiguration
。您可以通过查看 https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapProperties.java.
@Configuration
@EnableLdapRepositories(basePackages="com.yyy.repository.ldap", ldapTemplateRef="ldapTemplate2")
public class LdapConfiguration2 {
@Autowired
private Environment environment;
@Bean(name="ldapProperties2")
@ConfigurationProperties(prefix="spring.ldap2")
public LdapProperties ldapProperties() {
return new LdapProperties();
}
@Bean(name="contextSource2")
public LdapContextSource contextSourceTarget(@Qualifier("ldapProperties2") LdapProperties ldapProperties) {
LdapContextSource source = new LdapContextSource();
source.setUserDn(this.properties.getUsername());
source.setPassword(this.properties.getPassword());
source.setBase(this.properties.getBase());
source.setUrls(this.properties.determineUrls(this.environment));
source.setBaseEnvironmentProperties(Collections.<String,Object>unmodifiableMap(this.properties.getBaseEnvironment()));
return source;
}
@Bean(name="ldapTemplate2")
public LdapTemplate ldapTemplate(@Qualifier("contextSource2") LdapContextSource contextSource){
return new LdapTemplate(contextSource);
}
}
LdapConfiguration2
将由application.properties
中的spring.ldap2
前缀配置。
2) 我不认为扩展存储库是解决方案。我建议创建一个 @Service
方法来遍历您的存储库并应用更新。我将在下面提供两种方法。
示例 1)
@Service
public class UpdateRepositories {
public void updateAllRepositories(LdapUserRepository userRepository1, LdapUserRepository userRepository2) {
// apply updates to userRepository1 and userRepository2
}
}
示例 2)
@Service
public class UpdateRepositories {
public void updateAllRepositories(ApplicationContext appContext) {
Map<String, LdapRepository> ldapRepositories = appContext.getBeansofType(LdapRepository.class)
// iterate through map and apply updates
}
}
我还没有编译这段代码,所以如果有什么地方不对或者您需要额外的指导,请告诉我。
我不知道我是否理解正确,但这是我们所做的:
全局配置class
@Bean("odm") public ObjectDirectoryMapper odm() { return new DefaultObjectDirectoryMapper(); };
第一次 LDAP 配置class
@Configuration @PropertySource("classpath:ldap-one.properties") public class LdapOneConfiguration { @Autowired Environment ldapProperties; @Bean(name = "contextSourceOne") public LdapContextSourceCustom contextSourceLdapOneTarget() { LdapContextSourceCustom ldapContextSource = new LdapContextSourceCustom(); ldapContextSource.setUrl(ldapProperties.getProperty("ldap-one.url")); ldapContextSource.setBase(ldapProperties.getProperty("ldap-one.base")); ldapContextSource.setUserDn(ldapProperties.getProperty("ldap-one.userDn")); ldapContextSource.setPassword(ldapProperties.getProperty("ldap-one.password")); ldapContextSource.setKeyStoreFile(ldapProperties.getProperty("ldap-one.truststore")); return ldapContextSource; } @Bean(name = "ldapTemplateOne") public LdapTemplate ldapOneTemplate(@Qualifier("contextSourceOne") LdapContextSourceCustom contextSource) { return new LdapTemplate(contextSource); } @Bean(name = "ldapUserRepoOne") public LdapUserRepository ldapUserRepositoryOne(@Qualifier("ldapTemplateOne") LdapTemplate ldapTemplate, @Qualifier("odm") ObjectDirectoryMapper odm) { return new LdapUserRepository(ldapTemplate, odm); } @Bean(name = "ldapFamilyRepoOne") public LdapFamilyRepository ldapFamilyRepositoryOne(@Qualifier("ldapTemplateOne") LdapTemplate ldapTemplate, @Qualifier("odm") ObjectDirectoryMapper odm) { return new LdapFamilyRepository(ldapTemplate, odm); } }
第二个 LDAP 配置class
@Configuration @PropertySource("classpath:ldap-two.properties") public class LdapTwoConfiguration { @Autowired Environment ldapProperties; @Bean(name = "contextSourceTwo") public LdapContextSourceCustom contextSourceLdapTwoTarget() { LdapContextSourceCustom ldapContextSource = new LdapContextSourceCustom(); ldapContextSource.setUrl(ldapProperties.getProperty("ldap-two.url")); ldapContextSource.setBase(ldapProperties.getProperty("ldap-two.base")); ldapContextSource.setUserDn(ldapProperties.getProperty("ldap-two.userDn")); ldapContextSource.setPassword(ldapProperties.getProperty("ldap-two.password")); ldapContextSource.setKeyStoreFile(ldapProperties.getProperty("ldap-two.truststore")); return ldapContextSource; } @Bean(name = "ldapTemplateTwo") public LdapTemplate ldapTwoTemplate(@Qualifier("contextSourceTwo") LdapContextSourceCustom contextSource) { return new LdapTemplate(contextSource); } @Bean(name = "ldapUserRepoTwo") public LdapUserRepository ldapUserRepositoryTwo(@Qualifier("ldapTemplateTwo") LdapTemplate ldapTemplate, @Qualifier("odm") ObjectDirectoryMapper odm) { return new LdapUserRepository(ldapTemplate, odm); } @Bean(name = "ldapFamilyRepoTwo") public LdapFamilyRepository ldapFamilyRepositoryTwo(@Qualifier("ldapTemplateTwo") LdapTemplate ldapTemplate, @Qualifier("odm") ObjectDirectoryMapper odm) { return new LdapFamilyRepository(ldapTemplate, odm); } }
Ldap 用户存储库
public class LdapUserRepository extends SimpleLdapRepository<LdapUser> { public LdapUserRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm) { super(ldapOperations, odm, LdapUser.class); } }
LdapFamily 存储库
public class LdapFamilyRepository extends SimpleLdapRepository<LdapFamily> { public LdapFamilyRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm) { super(ldapOperations, odm, LdapFamily.class); } }
LdapUser 服务(与 LdapFamily 服务相同)
@Service public class LdapUserServiceImpl implements LdapUserService { @Autowired private ApplicationContext appContext; private LdapUserRepository uniqueLdapUserRepo; private List<LdapUserRepository> ldapUserRepoList; @PostConstruct private void setUniqueRepo() { uniqueLdapUserRepo = appContext.getBeansOfType(LdapUserRepository.class).values().iterator().next(); ldapUserRepoList = new ArrayList<>(appContext.getBeansOfType(LdapUserRepository.class).values()); } @Override public LdapUser getUser(String uid) { return uniqueLdapUserRepo.findOne(query().where("uid").is(uid)); } @Override public void saveUser(LdapUser user) { for(LdapUserRepository repo: ldapUserRepoList){ repo.save(user); } }
}
我们删除了 LDAP 存储库的自动配置:
@EnableLdapRepositories(basePackages = "com.afklm.paul.repository.ldap", ldapTemplateRef = "ldapTwoTemplate")
感谢 ryan2049 的帮助。
现在实际上有一个更简单的方法:
创建多个配置,用 @EnableLdapRepositories 注释并具有相应的属性
创建第一个配置
@Configuration
@EnableLdapRepositories(basePackages = "first.ldap.package.repository.**", ldapTemplateRef = "firstLdapTemplate")
public class FirstLDAPConfig {
....detail
@Bean("firstLdapTemplate")
public LdapTemplate firstLdapTemplate() {
...template creation
}
}
创建第二个配置
@Configuration
@EnableLdapRepositories(basePackages = "second.ldap.package.repository.**", ldapTemplateRef = "secondLdapTemplate")
public class SecondLDAPConfig {
....detail
@Bean("secondLdapTemplate")
public LdapTemplate secondLdapTemplate() {
...template creation
}
}
每个配置都应该处理它自己的 contextSource 那么只有 EnableLdapRepositories 注释中的指定存储库才会使用该特定的 ContextSource 和 LdapTemplate