2

I would like to use Spring Actuator Framework in my Spring Boot 2.0 application. The framework itself works as expected, thus I am able to reach e.g. my /actuator/health endpoint. There I´m presented a login dialogue. I´d like to get rid of it and tried the following:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfiguration {

  @Bean
  public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {

    return http
               .authorizeExchange()
                   .matchers(EndpointRequest.to("prometheus")).permitAll()
                   .matchers(EndpointRequest.toAnyEndpoint()).authenticated()
                   .anyExchange().permitAll()
                   .and()
               .formLogin()
                  .and()
               .httpBasic()
                  .and()
               .build();
  }

However, during application startup I get the following error:

Failed to instantiate [org.springframework.security.web.server.SecurityWebFilterChain]: Factory method 'securityWebFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: authenticationManager cannot be null

Of course I tried to search for it, but I always only get pages describing different scenarios or security configuration with Spring Boot 1.x framework. Can anybody help me here?

dur
  • 15,689
  • 25
  • 79
  • 125
EllisTheEllice
  • 905
  • 3
  • 14
  • 33

2 Answers2

2

Off the top of my head, the easiest way to do it should be to have your SecurityConfiguration extend WebSecurityConfigurerAdapter and override configure(WebSecurity web), like so:

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers("/actuator/**");
    }

    // ...

}

Also, I'm not familiar with @EnableWebFluxSecurity, but for the above to work, you'd need both the @Configuration and the @EnableWebSecurity annotation.

Now as for the way your configuration is setup, it's not really optimal. To complement the above suggestion, you should configure your security using HttpSecurity instead of using your current SecurityWebFilterChain.

TwiN
  • 3,554
  • 1
  • 20
  • 31
  • Hi, thanks for your suggestions. _To complement the above suggestion, you should configure your security using HttpSecurity instead of using your current SecurityWebFilterChain_ Can you tell me, how to do that? I´ve never configured something for the use of SecurityWebFilterChain – EllisTheEllice Apr 30 '18 at 07:14
1

Although the answer from Twin has already received upvotes and the question is old: if you want to secure the Actuator endpoints by using Basic Auth, you also need to provide a suitable AuthenticationManager. The AuthenticationManager authenticates a username+password against some kind of repository.

In the following example the request is authenticated against a user defined in application.yml:

SecurityConfig

@RequiredArgsConstructor
@Configuration
public class SecurityConfig {

  private final SecurityProperties securityProperties;

  @Bean
  public SecurityWebFilterChain actuator(ServerHttpSecurity http) {
    return http
        .authorizeExchange()
        .matchers(EndpointRequest.toAnyEndpoint().excluding("prometheus")).hasRole("ACTUATOR")
        .anyExchange().permitAll()
        .and()
        .httpBasic()
        .authenticationManager(new UserDetailsRepositoryReactiveAuthenticationManager(
            new MapReactiveUserDetailsService(new User(securityProperties.getUser().getName(),
                "{noop}".concat(securityProperties.getUser().getPassword()),
                securityProperties.getUser().getRoles().stream().map("ROLE_"::concat).map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toList())))))
        .securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
        .and()
        .requestCache().disable() // disables websession creation
        .build();
  }
}

application.yml

spring:
  security:
    user:
      name: username
      password: password
      roles: ACTUATOR

This is not production ready, you shouldn't place the password in your sourcecode.

judomu
  • 518
  • 4
  • 13