繁体   English   中英

Spring Boot Actuator Endpoints 安全性不适用于自定义 Spring 安全配置

[英]Spring Boot Actuator Endpoints security doesn't work with custom Spring Security Configuration

这是我的 Spring Boot 1.5.1 Actuator application.properties

#Spring Boot Actuator
management.contextPath: /actuator
management.security.roles=R_0

这是我的WebSecurityConfig

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Value("${logout.success.url}")
    private String logoutSuccessUrl;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // @formatter:off
        http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);

        http
            .csrf().ignoringAntMatchers("/v1.0/**", "/logout")
        .and()
            .authorizeRequests()

            .antMatchers("/oauth/authorize").authenticated()
            //Anyone can access the urls
            .antMatchers("/signin/**").permitAll()
            .antMatchers("/v1.0/**").permitAll()
            .antMatchers("/auth/**").permitAll()
            .antMatchers("/actuator/health").permitAll()
            .antMatchers("/actuator/**").hasAuthority("R_0")
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
        .and()
            .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .failureUrl("/login?error=true")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
            .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl(logoutSuccessUrl)
                    .permitAll();
        // @formatter:on
    }

    /**
     * Configures the authentication manager bean which processes authentication requests.
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

现在我可以使用具有R_0权限的正确用户成功登录我的应用程序但是当我尝试访问时

http://localhost:8080/api/actuator/beans

我收到以下错误:

There was an unexpected error (type=Forbidden, status=403).
Access is denied. User must have one of the these roles: R_0

如何正确配置 Spring Boot Actuator 以了解正确的Authentication

现在为了让它工作我必须做以下技巧:

management.security.enabled=false

.antMatchers("/actuator/health").permitAll()
.antMatchers("/actuator/**").hasAuthority("R_0")

是否有机会以正确的方式配置 Actuator?

更新

我正在使用UserDetailsService.UserDetails.Authorities

    public Collection<? extends GrantedAuthority> getAuthorities() {
        String[] authorities = permissions.stream().map(p -> {
            return p.getName();
        }).toArray(String[]::new);
        return AuthorityUtils.createAuthorityList(authorities);
    }

您必须为management.security.roles使用前缀ROLE_例如management.security.roles=ROLE_SOMENAME才能解决此问题

要获得 spring boot actuator 端点的授权,您需要具有ACTUATOR角色。 请参阅此示例使用 Spring Security 访问受限执行器端点

我来自 Reactive Spring Boot 2.x 应用程序并遇到了这个问题并通过更新 WebSecurityConfig.securityWebFilterChain 以及 SecurityContextRepository.load 以包含 /actuator/** 来解决它,如下所示:

public class WebSecurityConfig {
  private AuthenticationManager authenticationManager;

  private SecurityContextRepository securityContextRepository;

  @Autowired
  public WebSecurityConfig(AuthenticationManager authenticationManager, SecurityContextRepository securityContextRepository) {
    this.authenticationManager = authenticationManager;
    this.securityContextRepository = securityContextRepository;
  }

  @Bean
  public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    return http
      .exceptionHandling()
      .authenticationEntryPoint((swe, e) -> Mono.fromRunnable(() -> {
        swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
      })).accessDeniedHandler((swe, e) -> Mono.fromRunnable(() -> {
        swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
      })).and()
      .csrf().disable()
      .formLogin().disable()
      .httpBasic().disable()
      .authenticationManager(authenticationManager)
      .securityContextRepository(securityContextRepository)
      .authorizeExchange()
      .pathMatchers("/actuator/**").permitAll()
      .anyExchange().authenticated()
      .and().build();
  }

以及更新

@Slf4j
@Component
public class SecurityContextRepository implements ServerSecurityContextRepository {

  private AuthenticationManager authenticationManager;

  public SecurityContextRepository(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
  }

  @Override
  public Mono<Void> save(ServerWebExchange swe, SecurityContext sc) {
    return Mono.error(new UnsupportedOperationException("Not supported"));
  }

  @Override
  public Mono<SecurityContext> load(ServerWebExchange swe) {
    ServerHttpRequest request = swe.getRequest();

    if (request.getPath().value().startsWith("/actuator") ) {
      return Mono.empty();
    }
    // other authentication logic here
  }
1
1.You can add the following properties
endpoints.health.enabled=true
endpoints.loggers.enabled=true
endpoints.metrics.enabled=true

endpoints.env.enabled=false
endpoints.configprops.enabled=false
endpoints.autoconfig.enabled=false
endpoints.info.enabled=false

management.context-path=/management

2)
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ApplicationContextAware {

    private static final String ACTUATOR = "ACTUATOR";
    private static final String ROLE1 = "USER";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/controllerpath/**")
                .hasAnyRole(ROLE1).antMatchers("/loggers/**","/metrics/**","/health/**").hasAnyRole(ACTUATOR).and()

                .csrf().disable().headers().frameOptions().disable();

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("username-of-app").password("encryptedpassword")
                .roles(ROLE1).and().withUser("username-of-management-for-path")
                .password("encrypted password").roles(ACTUATOR);

    }
}
  1. 您可以添加以下属性
    endpoints.health.enabled=true
    endpoints.loggers.enabled=true
    endpoints.metrics.enabled=true
    
    endpoints.env.enabled=false
    endpoints.configprops.enabled=false
    endpoints.autoconfig.enabled=false
    endpoints.info.enabled=false
    
    management.context-path=/management
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ApplicationContextAware {
    
        private static final String ACTUATOR = "ACTUATOR";
        private static final String ROLE1 = "USER";
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.httpBasic().and().authorizeRequests().antMatchers("/controllerpath/**")
                    .hasAnyRole(ROLE1).antMatchers("/loggers/**","/metrics/**","/health/**").hasAnyRole(ACTUATOR).and()
    
                    .csrf().disable().headers().frameOptions().disable();
    
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
            auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("username-of-app").password("encryptedpassword")
                    .roles(ROLE1).and().withUser("username-of-management-for-path")
                    .password("encrypted password").roles(ACTUATOR);
    
        }
    }

根据此链接:

http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-monitoring.html

默认情况下,所有敏感的 HTTP 端点都是安全的,只有具有 ACTUATOR 角色的用户才能访问它们。 使用标准的 HttpServletRequest.isUserInRole 方法强制执行安全性。

如果您想要与 ACTUATOR 不同的东西,请使用 management.security.roles 属性。

所以我认为您所要做的就是在 application.properties 中设置以下属性。

management.security.roles

前任:

management.security.roles=R_0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM