0
votes

In a project using spring-security-ldap I need to perform some LDAP queries and I added spring-data-ldap. Suddenly I can't connect anymore to the embedded LDAP registry and I get:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'run': Invocation of init method failed; nested exception is org.springframework.ldap.CommunicationException: localhost:8389; nested exception is javax.naming.CommunicationException: localhost:8389 [Root exception is java.net.ConnectException: Connexion refusée (Connection refused)]

Here is the security config which work as expected:

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
  @Override
  protected void configure(HttpSecurity http) throws Exception
  {
    http.authorizeRequests().antMatchers("/admins").hasRole("ADMINS")
      .antMatchers("/users").hasRole("USERS")
      .anyRequest().fullyAuthenticated()
      .and()
      .httpBasic();
  }

  @Override
  public void configure(AuthenticationManagerBuilder auth) throws Exception
  {
    auth
      .ldapAuthentication()
      .userDnPatterns("uid={0},ou=people")
      .userSearchBase("ou=people")
      .userSearchFilter("uid={0}")
      .groupSearchBase("ou=groups")
      .groupSearchFilter("uniqueMember={0}")
      .contextSource(contextSource())
      .passwordCompare()
      .passwordAttribute("userPassword");
  }

  @Bean
  public DefaultSpringSecurityContextSource contextSource()
  {
    log.info("*** SpringSecurityConfig.contextSource(): Inside contextSource");
    DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
    Arrays.asList("ldap://localhost:8389/"), "dc=toto,dc=com");
    contextSource.afterPropertiesSet();
    return contextSource;
  }
}

Now, if I want to use spring-data-ldap, I add this:

@Repository
public interface MyLdapRepository extends LdapRepository<LdapUser>
{
}

@Entry(base="ou=users", objectClasses = {"person", "inetOrgPerson", "top"})
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class LdapUser
{
  @Id
  private Name id;
  @Attribute(name = "uid")
  private String uid;
  @Attribute(name = "cn")
  private String cn;
}

And I try to make some queries, for example:

@SpringBootApplication
@Slf4j
public class Run extends SpringBootServletInitializer
{
  @Autowired
  private RdfLdapRepository rdfLdapRespository;

  public static void main(String[] args)
  {
    SpringApplication.run(Run.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)
  {
    return builder.sources(Run.class);
  }

  @PostConstruct
  public void setup()
  {
    log.info("### setup(): the LDIF file has been loaded");
    Iterable<LdapUser> users = rdfLdapRespository.findAll();
    users.forEach(user -> log.info("\"### setup(): names {}", user.getUid()));
  }
}

I get Connection Refused. Commenting out the setup() method, everything works as expected again. I suspect some missmatch between the Ldaptemplate used by spring-data-ldap and the DefaultSpringSecurityContextSource in the security config.

Does anyone know what might be the problem here ?

Many thanks in advance;

Kind regards,

Nicolas

1

1 Answers

0
votes

Problem solved. Everything was due to the fact that another instance of the Spring embedded LDAP directory server was running in the same Tomcat container. I'm not sure how this interacted with the spring-data-ldap and why it appeared only in this context but using the following command was capital as it helped me understand the issue:

> lsof -i:8389

This way I noticed that another LDAP embedded server was active and I understood why (consequence of repetitive deployment on the same Tomcat container).