Spring Security 教程(19)、高级网站功能

Remember-Me:自动登录功能

Spring Security 配图
Spring Security 配图
Spring Security 配图

Remember-Me 让用户在关闭浏览器后仍能保持登录状态。它通过 Cookie 实现,服务器在 Cookie 中存储用户的认证信息(加密签名)。

1
2
3
4
5
http.rememberMe()
.key("myAppKey") // 用于签名的密钥
.tokenValiditySeconds(86400 * 30) // Token 有效期 30 天
.rememberMeParameter("remember-me") // 表单字段名
.userDetailsService(userDetailsService);

安全提醒:

  • key 必须足够长(至少 20 个字符)且随机,防止 Token 被伪造
  • Token 有效期不宜过长,生产环境建议不超过 7 天
  • Remember-Me Cookie 包含敏感信息(用户名),不要存储在不安全的设备上

通道安全:HTTP vs HTTPS

如果你的应用同时支持 HTTP 和 HTTPS,可以配置特定 URL 只允许通过 HTTPS 访问:

1
2
3
4
5
http.requiresChannel()
.requestMatchers(request -> request.getRequestURI().contains("/admin"))
.requiresSecure()
.anyRequest()
.requiresInsecure();

CSRF 防护详解

CSRF(跨站请求伪造)攻击利用用户的已认证状态发起恶意请求。Spring Security 默认启用 CSRF 防护。

1
2
3
http.csrf()
.csrfTokenRepository(CsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers("/api/**");

对于前后端分离的 API 应用,通常需要:

  1. 关闭 CSRF 防护(使用 JWT 等无状态认证)
  2. 或者在前端手动添加 CSRF Token 到请求头
1
2
3
4
5
6
7
// 从 Meta 标签读取 CSRF Token
const token = document.querySelector('meta[name="_csrf"]').content;
const header = document.querySelector('meta[name="_csrf_header"]').content;

fetch('/api/data', {
headers: { [header]: token }
});

会话固定攻击防护

advanced-web 配图
advanced-web 配图
advanced-web 配图

Spring Security 默认在认证成功后创建新的 Session,防止攻击者利用已知的 Session ID。

1
2
3
http.sessionManagement()
.sessionFixation()
.migrateSession(); // 默认值,创建新 Session

可选策略:

  • migrateSession():创建新 Session,保留旧 Session 属性
  • newSession():创建全新 Session,丢弃旧 Session 属性
  • none():不处理,沿用旧 Session(不安全)