68%的Spring Boot安全配置错误,源于那些看起来没问题的配置——它们不会报错,没有异常,日志里干干净净。端点正常返回200,你直到别人发现才知道出事。
这就是上一篇提到的真实案例:Actuator在生产环境运行,/env和/metrics无需凭证直接返回数据。问题根源是Spring Boot 3的默认配置不会自动锁定你不知道的端点。我们关闭了错误端点,但残留的授权模型是继承的、隐式的、脆弱的,必须重建。
![]()
核心观点:默认继承的授权模型,技术上比显式模型更危险,即使两者今天表现相同。因为前者在更新依赖或添加端点时会静默失效,后者会尖叫报警。
![]()
事故前的SecurityFilterChain没有为Actuator单独配置,依赖Spring Security 6的默认行为和application.yml属性。结果是:任何Spring Boot版本更新都可能破坏安全契约,而构建流程毫无感知。
这是绝对不能出现的配置:
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有端点——生产环境灾难
endpoint:
health:
show-details: always # 向任何人暴露堆栈跟踪和内部详情
include: "*"会暴露/actuator/env、/actuator/heapdump、/actuator/threaddump、/actuator/loggers等敏感端点。show-details: always则让健康端点向任意IP返回数据源详情、依赖状态和内部错误信息。
![]()
问题不只是"谁能看到什么",而是模型不够显式。没人能仅凭代码理解安全意图,必须掌握该版本Spring Boot的默认行为才行。
重建从设计决策开始:Actuator需要独立的SecurityFilterChain,与主应用链分离。Spring Security 6配合Spring Boot 3.x原生支持@Order注解实现这一点。
// 专为Actuator的独立链——显式排序在主链之前
@Bean
@Order(1)
public SecurityFilterChain actuatorSecurityFilterChain(HttpSecurity http) throws Exception {
http
.securityMatcher("/actuator/**") // 仅匹配Actuator路由
.authorizeHttpRequests(auth -> auth
// 仅健康检查公开——供Railway/k8s探针使用,无内部详情
.requestMatchers("/actuator/health/liveness").permitAll()
.requestMatchers("/actuator/health/readiness").permitAll()
// 其余所有Actuator端点需认证
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults()); // 基础认证,非生产环境方案
return http.build();
}
关键改进:securityMatcher限定作用域,@Order(1)确保优先处理,任何新增端点默认落入authenticated()保护。显式模型让安全意图可读、可审计、可测试。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.