Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security WebFlux and LDAP

What customization's are required in order to secure a Reactive Spring Boot application with LDAP? The examples I've seen so far are based on Spring MVC and the example for securing a WebFlux only shows a simple Reactive example with an in-memory Map.

like image 745
franktylerva Avatar asked May 24 '18 10:05

franktylerva


1 Answers

Here is one solution for this that I have come up with and tested.

Deserving special attention is this information in this class: ReactiveAuthenticationManagerAdapter. There, it states:

Adapts an AuthenticationManager to the reactive APIs. This is somewhat necessary because many of the ways that credentials are stored (i.e. JDBC, LDAP, etc) do not have reactive implementations. What's more is it is generally considered best practice to store passwords in a hash that is intentionally slow which would block ever request from coming in unless it was put on another thread.

First, create a configuration class. This will handle the connectivity to LDAP.

@Configuration
public class ReactiveLdapAuthenticationConfig {

    // Set this in your application.properties, or hardcode if you want.
    @Value("${spring.ldap.urls}")
    private String ldapUrl;

    @Bean
    ReactiveAuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {

        BindAuthenticator ba = new BindAuthenticator(contextSource);
        ba.setUserDnPatterns(new String[] { "cn={0},ou=people" } );

        LdapAuthenticationProvider lap = new LdapAuthenticationProvider(ba);

        AuthenticationManager am = new ProviderManager(Arrays.asList(lap));

        return new ReactiveAuthenticationManagerAdapter(am);

    }

    @Bean
    BaseLdapPathContextSource contextSource() {
        LdapContextSource ctx = new LdapContextSource();
        ctx.setUrl(ldapUrl);
        ctx.afterPropertiesSet();
        return ctx;
    }

}

After that, you'll want to configure your security following the patterns here. The most basic chain configuration is about this:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        .authorizeExchange()
            .anyExchange().authenticated()
            .and()
        .httpBasic();

    return http.build();
}

For completeness, you'll want to make sure you have these:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-ldap</artifactId>
</dependency>

Other References

  • EnableReactiveMethodSecurity
  • BindAuthenticator
  • LdapAuthenticationProvider
  • ProviderManager
like image 111
Brian Avatar answered Nov 15 '22 15:11

Brian