Spring Endpoint protection on boot does not work with custom Spring Security Configuration

This is my Spring Boot 1.5.1 application.properties statement:

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

This is my 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(); } } 

Now I can successfully log into my application with the right user with R_0 privileges, but when I try to access, for example,

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

I get the 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 properly configure Spring Boot Actuator to know the correct Authentication ?

Right now, to make it work, I have to do the following trick:

 management.security.enabled=false .antMatchers("/actuator/health").permitAll() .antMatchers("/actuator/**").hasAuthority("R_0") 

Is it likely to configure Actuator correctly?

UPDATED

I am using UserDetailsService.UserDetails.Authorities

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

To solve this problem, you need to use the ROLE_ prefix for management.security.roles for example management.security.roles=ROLE_SOMENAME

+5
source

To get authorization for the spring actuator endpoints, you need to have the ACTUATOR role. See This Example. Accessing Endpoints of a Limited Actuator Using Spring Security

0
source

I came to this from a Reactive Spring Boot 2.x application, and this problem was resolved by updating WebSecurityConfig.securityWebFilterChain as well as SecurityContextRepository.load to include / activator / ** as follows:

 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 update

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

According to this link:

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

By default, all confidential HTTP endpoints are protected so that only users with the ACTUATOR role can access them. Security using the standard HttpServletRequest.isUserInRole method.

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

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

 management.security.roles 

Example:

 management.security.roles=R_0 
-one
source

Source: https://habr.com/ru/post/1014854/


All Articles