![](/img/trans.png)
[英]Spring: Configure security for actuator endpoints with Spring Security
[英]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);
}
}
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.