name: springboot-security description: Java Spring Boot 服务中的认证/授权、验证、CSRF、密钥管理、安全头、速率限制和依赖项安全的最佳实践。
Spring Boot 安全审查
在添加认证、处理输入、创建端点或处理密钥时使用。
认证
- 优先使用无状态JWT或带有吊销列表的不透明令牌
- 会话使用
httpOnly、Secure、SameSite=StrictCookie - 在
OncePerRequestFilter或资源服务器中验证令牌
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtService jwtService;
public JwtAuthFilter(JwtService jwtService) {
this.jwtService = jwtService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
Authentication auth = jwtService.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
chain.doFilter(request, response);
}
}
授权
- 启用方法级安全:
@EnableMethodSecurity - 使用
@PreAuthorize("hasRole('ADMIN')")或@PreAuthorize("@authz.canEdit(#id)") - 默认拒绝,仅公开必要的范围
输入验证
- 在控制器中使用
@Valid进行Bean验证 - 在DTO上应用约束:
@NotBlank、@Email、@Size、自定义验证器 - 渲染前使用白名单对HTML进行消毒
SQL注入防护
- 使用Spring Data仓库或参数化查询
- 对于原生查询,使用
:param绑定,不要拼接字符串
CSRF防护
- 对于浏览器会话应用,启用CSRF,并在表单/头部包含令牌
- 对于使用Bearer令牌的纯API,禁用CSRF并依赖无状态认证
http
.csrf(csrf -> csrf.disable())
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
密钥管理
- 不要在源代码中包含密钥。从环境变量或保险库加载
- 保持
application.yml无凭据,使用占位符 - 定期轮换令牌和数据库凭据
安全头
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'"))
.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
.xssProtection(Customizer.withDefaults())
.referrerPolicy(rp -> rp.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER)));
速率限制
- 对高成本端点应用Bucket4j或网关级限制
- 记录突发情况并发送警报,返回带有重试提示的429状态码
依赖项安全
- 在CI中运行OWASP Dependency Check / Snyk
- 保持Spring Boot和Spring Security在受支持的版本
- 对已知CVE使构建失败
日志记录与PII
- 不要记录密钥、令牌、密码、完整的PAN数据
- 编辑敏感字段,并使用结构化JSON日志记录
文件上传
- 验证大小、内容类型、扩展名
- 存储在Web根目录之外,并根据需要进行扫描
发布前检查清单
- [ ] 认证令牌被正确验证且已过期
- [ ] 所有敏感路径都有授权保护
- [ ] 所有输入都经过验证和消毒
- [ ] 没有字符串拼接的SQL
- [ ] 针对应用类型的CSRF防护正确
- [ ] 密钥已外部化且未提交
- [ ] 安全头已设置
- [ ] API有速率限制
- [ ] 依赖项已扫描且是最新的
- [ ] 日志中无敏感数据
注意:默认拒绝,验证输入,应用最小权限,优先使用配置进行安全防护。