3

我想使用 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> {

}

知道怎么做吗?

提前感谢您的帮助。

4

3 回答 3

4

1)可以指定多个 LDAP 存储库配置。请看下面的例子。[注意:这取决于spring-boot库]

@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);
    }
}

您可以使用spring.ldap前缀 inapplication.properties来配置上述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将由中的spring.ldap2前缀配置application.properties

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
    }
}

我还没有编译这段代码,所以如果有什么问题或者你需要额外的指导,请告诉我。

于 2017-07-26T14:50:34.473 回答
3

我不知道我是否理解正确,但这是我们所做的:

  1. 全局配置类

    @Bean("odm")
    public ObjectDirectoryMapper odm() {
        return new DefaultObjectDirectoryMapper();
    };
    
  2. 第一个 LDAP 配置类

    @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);
        }
    }
    
  3. 第二个 LDAP 配置类

    @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);
        }
    
    }
    
  4. LdapUser 存储库

    public class LdapUserRepository extends SimpleLdapRepository<LdapUser> {
    
        public LdapUserRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm) {
            super(ldapOperations, odm, LdapUser.class);
        }
    }
    
  5. LdapFamily 存储库

    public class LdapFamilyRepository extends SimpleLdapRepository<LdapFamily> {
    
        public LdapFamilyRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm) {
            super(ldapOperations, odm, LdapFamily.class);
        }
    }
    
  6. 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 repo 的自动配置:

@EnableLdapRepositories(basePackages = "com.afklm.paul.repository.ldap", ldapTemplateRef = "ldapTwoTemplate")

感谢 ryan2049 的帮助。

于 2017-07-27T14:04:01.560 回答
1

现在实际上有一个更简单的方法:

创建多个使用@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

于 2018-10-11T20:48:53.883 回答