为 Spring Boot 2.0 acuator 框架配置安全性

Configure security for Spring Boot 2.0 acuator framework

我想在我的 Spring Boot 2.0 应用程序中使用 Spring 执行器框架。框架本身按预期工作,因此我能够达到例如我的 /actuator/health 端点。我在那里展示了一个登录对话框。我想摆脱它并尝试了以下方法:

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

但是,在应用程序启动过程中出现以下错误:

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

当然我试图搜索它,但我总是只得到描述不同场景或使用 Spring Boot 1.x 框架的安全配置的页面。有人可以帮我吗?

我没想到,最简单的方法应该是让您的 SecurityConfiguration 扩展 WebSecurityConfigurerAdapter 并覆盖 configure(WebSecurity web),如下所示:

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

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

    // ...

}

此外,我不熟悉 @EnableWebFluxSecurity,但要使上述工作正常,您需要 @Configuration@EnableWebSecurity 注释。

现在至于您的配置设置方式,它并不是真正的最佳选择。为了补充上述建议,您应该使用 HttpSecurity 配置安全性,而不是使用当前的 SecurityWebFilterChain.

尽管 Twin 的回答已经获得赞成并且问题是旧的:如果您想使用 Basic Auth 来保护 Actuator 端点,您还需要提供合适的 AuthenticationManager。 AuthenticationManager 根据某种存储库验证用户名+密码。

在以下示例中,请求针对 application.yml 中定义的用户进行身份验证:

安全配置

@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

这不是生产就绪的,你不应该把密码放在你的源代码中。