web-dev-qa-db-ja.com

Spring Boot Actuator Endpointsセキュリティは、カスタムのSpring Security構成では機能しません

これは私のSpring Boot 1.5.1アクチュエータ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

正しいAuthenticationを認識するために、Spring Boot Actuatorを正しく構成する方法は?

今、それを機能させるために、私は次のトリックをしなければなりません:

management.security.enabled=false

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

アクチュエータを正しい方法で設定する機会はありますか?

[〜#〜] updated [〜#〜]

UserDetailsService.UserDetails.Authoritiesを使用しています

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

この問題を解決するには、ROLE_の接頭辞management.security.rolesを使用する必要があります。たとえば、management.security.roles=ROLE_SOMENAME

5
alexanoid

私は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
  }
0
Mitch1077487

スプリングブートアクチュエータエンドポイントの承認を得るには、[〜#〜] actuator [〜#〜]ロールが必要です。この例を参照してください Spring Securityによる制限付きアクチュエータエンドポイントへのアクセス

0
Dhiraj Ray