2

This is in continuation of the question, Multiple WebsecurityConfigurerAdapter, I was able to successfully make two WebsecurityConfigurerAdapter work with two different security configurations. Now there are few microservices which have been upgraded to SpringBoot 2 with reactive webflux framework. Here too I want to do the same, where all apis are secured with jwt token and actuator apis are secured using basic auth. Here is my code

ActuatorSecurityConfig

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@EnableWebFluxSecurity
public class ActuatorWebfluxSecurityConfig {

    @Value("${spring.security.user.name:admin}")
    private String userName;

    @Value("${spring.security.user.password:admin}")
    private String userPassword;

    @Value("${spring.security.user.roles:ADMIN}")
    private String userRole;

    @Bean
    PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Order(-1)
    SecurityWebFilterChain springWebfluxSecurityFilterChain(ServerHttpSecurity http) {

        http.csrf().disable()
                .authenticationManager(authManager())
                .authorizeExchange().pathMatchers("/actuator/**").authenticated()
                .anyExchange().authenticated()
                .and()
                .httpBasic()
        ;
        return http.build();
    }

    public MapReactiveUserDetailsService userDetailsService() {
        UserDetails admin = User.builder()
                .username(userName)
                //.password(encoder().encode(userPassword))
                .password("{noop}" + userPassword)
                //.passwordEncoder(encoder())
                .roles(userRole)
                .build();
        return new MapReactiveUserDetailsService(admin);
    }

    private ReactiveAuthenticationManager authManager() {
        return new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService());
    }

Regular security Config

@EnableWebFluxSecurity
public class SecurityConfig {

    private static final String[] AUTH_WHITELIST = {
            "/docs/**",
            "/swagger-ui.html",
            "/swagger-resources",
            "/swagger-resources/**",
            "/v2/api-docs"
    };

    @Bean
    @Order(2)
    SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.csrf().disable()
                .authorizeExchange()
                .pathMatchers(HttpMethod.OPTIONS, "/abc/**")
                .permitAll()
                .pathMatchers("/abc/**", "/xyz/**")
                .hasAuthority("ABC")
                .pathMatchers(AUTH_WHITELIST).permitAll()
                .and()
                .oauth2ResourceServer()
                .jwt().jwtAuthenticationConverter(grantedAuthoritiesExtractor())
        ;
        return http.build();
    }

    private Converter<Jwt, Mono<AbstractAuthenticationToken>> grantedAuthoritiesExtractor() {
        GrantedAuthoritiesExtractor extractor = new GrantedAuthoritiesExtractor();
        return new ReactiveJwtAuthenticationConverterAdapter(extractor);
    }
}

Both these configurations individually work. But when I try to make both of them work in together only the configuration with highest precedence work. Spring boot version is 2.1.5 and reactive spring security is 5.1.5

Tatha
  • 1,253
  • 2
  • 24
  • 42
  • 1
    Similarly to your previous question, you need to add a matcher for each filter chain `.securityMatcher()` – Eleftheria Stein-Kousathana Dec 31 '19 at 16:13
  • 1
    @EleftheriaStein-Kousathana i had done that before, but didn't solve the problem. The solution provided in the question shared by Thomas Andolf worked for me – Tatha Jan 02 '20 at 18:49

0 Answers0