Spring:通过Spring Security通用配置Actuator端点安全及区分同路径端点
关于Spring Security配置Actuator端点安全及区分不同端口同名端点的解决方案
一、能不能用Spring Security通用配置Actuator端点安全?
答案是肯定的,但确实需要通过自定义Spring Security配置来实现通用化控制。Spring Boot没有提供开箱即用的全局开关直接统一管控所有Actuator端点安全,但我们可以借助Spring Security的请求匹配器,精准定位所有Actuator端点,再统一配置安全规则。
举个简单的示例,假设要让所有Actuator端点都需要认证才能访问:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 统一匹配所有Actuator端点 .requestMatchers(request -> request.getServletPath().startsWith("/actuator/")) .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) // 配置应用其他端点的规则 .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) .formLogin(withDefaults()); return http.build(); } }
这里通过request.getServletPath().startsWith("/actuator/")匹配所有Actuator端点,统一设置认证要求,实现通用化配置。
二、如何区分8080端口的自定义/info和8081端口的Actuator info端点?
核心思路是通过请求的本地监听端口做区分——两个端点路径相同,但所在端口不同,Spring Security可以在请求匹配时获取端口信息,从而精准定位目标端点。
下面是具体配置示例,假设我们的需求是:
- 允许所有人访问8080端口的自定义
/info - 要求认证后才能访问8081端口的Actuator
/info
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 匹配8081端口的Actuator /info .requestMatchers(request -> request.getLocalPort() == 8081 && request.getServletPath().equals("/actuator/info")) .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) // 匹配8080端口的自定义/info .requestMatchers(request -> request.getLocalPort() == 8080 && request.getServletPath().equals("/info")) .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) // 其他端点的默认规则 .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) .formLogin(withDefaults()); return http.build(); } }
如果想让代码更优雅复用,可以把端口判断封装成自定义RequestMatcher:
class PortRequestMatcher implements RequestMatcher { private final int port; private final String path; PortRequestMatcher(int port, String path) { this.port = port; this.path = path; } @Override public boolean matches(HttpServletRequest request) { return request.getLocalPort() == port && request.getServletPath().equals(path); } }
然后在配置中使用:
.requestMatchers(new PortRequestMatcher(8081, "/actuator/info")) .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .requestMatchers(new PortRequestMatcher(8080, "/info")) .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
需要注意:确保应用确实通过server.port和management.server.port配置,分别在8080和8081端口监听,这样端口判断才能生效。
内容的提问来源于stack exchange,提问作者obecker
相关产品推荐
相关产品推荐

