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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42142556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:23:33  来源:igfitidea点击:

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

javaspringspring-bootspring-securityspring-boot-actuator

提问by alexanoid

This is my Spring Boot 1.5.1 Actuator application.properties:

这是我的 Spring Boot 1.5.1 执行器application.properties

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

This is my WebSecurityConfig:

这是我的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();
    }

}

Right now I'm successfully able to login in my application with a right user that has R_0authorities but when I trying to access for example

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

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

I receive a following error:

我收到以下错误:

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

How to correctly configure Spring Boot Actuator in order to be aware about the correct Authentication?

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

Right now in order to get it workin I have to do the following trick:

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

management.security.enabled=false

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

Is any chance to configure Actuator in a right way ?

有没有机会以正确的方式配置执行器?

UPDATED

更新

I'm using UserDetailsService.UserDetails.Authorities

我正在使用 UserDetailsService.UserDetails.Authorities

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

采纳答案by alexanoid

You have to use prefix ROLE_for your management.security.rolesfor example management.security.roles=ROLE_SOMENAMEin order to solve this issue

你必须使用前缀ROLE_为您management.security.roles例如 management.security.roles=ROLE_SOMENAME,为了解决这个问题

回答by Mitch1077487

I'm coming at this from a Reactive Spring Boot 2.x app and had this problem and solved it by updating the WebSecurityConfig.securityWebFilterChain as well as SecurityContextRepository.load to include /actuator/** as follows:

我是从 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();
  }

as well as updating

以及更新

@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
  }

回答by Dhiraj Ray

To have authorization to spring boot actuator endpoints you need to have ACTUATORrole. Refer this example Accessing Restricted Actuator Endpoints with Spring Security

要获得对 Spring Boot 执行器端点的授权,您需要具有ACTUATOR角色。请参阅此示例Accessing Restricted Actuator Endpoints with Spring Security

回答by mad_fox

According to this link:

根据这个链接:

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

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

By default all sensitive HTTP endpoints are secured such that only users that have an ACTUATOR role may access them. Security is enforced using the standard HttpServletRequest.isUserInRole method.

Use the management.security.roles property if you want something different to ACTUATOR.

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

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

So I think all you have to do is set the following property in application.properties.

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

management.security.roles

Ex:

前任:

management.security.roles=R_0