Spring Security从Redis获取会话信息?会话ID不匹配排查
Spring Session Redis 会话问题解答
1. 会话ID不匹配的原因及Redis键关联逻辑
- 会话ID不匹配的核心原因是Spring Session对原始会话ID做了编码处理:
- 默认使用
RedisIndexedSessionRepository时,Redis中存储的会话键格式为spring:session:sessions:<编码后的会话ID>,而响应返回的JSESSIONID是原始未编码的ID,两者自然不相等。编码逻辑由RedisSessionIdSerializer实现,通常会对原始ID做Base64或哈希转换,避免特殊字符干扰Redis键的存储。 - 另一种可能是开启了会话固定保护:Spring Security的
SessionFixationProtectionStrategy在用户登录成功后,会生成新的会话ID替换旧ID,此时Redis中存储的是新会话的编码ID,如果拿旧的JSESSIONID去对比Redis键,就会出现不匹配的情况。
- 默认使用
- Spring关联Redis键的方式:
- 由
RedisSessionRepository负责会话与Redis键的映射,它会将请求中提取的原始会话ID编码后,拼接成Redis的键名来查找会话数据。 - 同时维护两类索引键:
spring:session:expirations:<时间戳>用于管理会话过期,spring:session:sessions:index:principalName:<用户名>用于关联用户与所属会话,方便后续的会话管理操作。
- 由
2. 从Redis读取会话的过滤器及读取时机
- 负责读取Redis会话的过滤器是
SessionRepositoryFilter,它不属于Spring Security的过滤器链,而是Spring Session注入到Servlet容器的顶层过滤器,优先级高于所有Spring Security过滤器。 - 读取时机:在请求进入Spring Security过滤器链之前就会执行:
- 从请求的Cookie(或自定义请求头)中提取会话ID;
- 将提取到的ID编码后,去Redis中查找对应的会话数据;
- 将找到的会话对象绑定到当前请求的
HttpSession中,后续Spring Security的各类过滤器(如认证过滤器、权限拦截过滤器)直接从HttpSession中获取认证信息即可。
- 调试时找不到该过滤器的原因:因为它不在Spring Security的过滤器链里,需要查看Servlet容器的过滤器列表(比如Tomcat的Filter链)才能看到它的执行逻辑。
内容的提问来源于stack exchange,提问作者Johnyb
相关产品推荐
相关产品推荐

