【问题标题】:Multiple LDAP repositories with Spring LDAP Repository使用 Spring LDAP Repository 的多个 LDAP 存储库
【发布时间】:2018-01-01 08:38:18
【问题描述】:

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

}

知道怎么做吗?

提前感谢您的帮助。

【问题讨论】:

    标签: spring spring-ldap spring-repositories


    【解决方案1】:

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

    您可以使用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
        }
    }
    

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

    【讨论】:

    • 在示例 2 中,我只得到一个 LdapRepository(我认为是第一个实例化的)。
    • 此示例取决于您是否拥有多个 LdapRepository 实现。
    • 我用两个实体的完整示例添加了答案
    • 您是否有另一个 @Service 也负责家庭更新?
    • 是的,我为每个 LDAP 对象和尽可能多的存储库提供服务
    【解决方案2】:

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

    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 的帮助。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-06
        • 2020-07-24
        • 1970-01-01
        • 1970-01-01
        • 2011-04-15
        • 2015-10-12
        • 2012-10-05
        • 1970-01-01
        相关资源
        最近更新 更多