SaveSession GatewayFilter 工厂
SaveSession GatewayFilter 工厂会在将调用转发到下游之前强制执行 WebSession::save 操作。
当使用类似 Spring Session 这样的惰性数据存储时,这特别有用,因为你需要确保在转发调用之前会话状态已被保存。
以下示例配置了一个 SaveSession GatewayFilter:
示例 1. application.yml
yaml
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession重要提示: 如果你将 Spring Security 与 Spring Session 集成,并希望确保安全详细信息已转发到远程进程,这一点至关重要。
补充教学 —— 为什么要保存会话?
场景 1:确保会话数据持久化(分布式会话)
- 背景:使用 Spring Session + Redis 存储会话数据,Redis 采用惰性写入策略(即只在显式调用
save()时才写入)。 - 问题:网关在转发请求前,可能已经修改了会话中的某些属性(例如更新了用户权限、添加了临时令牌等),但如果没有显式保存,这些修改可能还在内存中,尚未写入 Redis。
- 后果:下游服务从 Redis 读取会话时,可能获取到的是旧数据,导致数据不一致。
- 解决:使用
SaveSession过滤器,确保在转发请求前,所有会话修改都已持久化到 Redis。- 流程:修改会话 →
SaveSession写入 Redis → 转发请求 → 下游服务读取最新数据
- 流程:修改会话 →
场景 2:Spring Security + Spring Session 集成(安全上下文传递)
- 背景:Spring Security 将认证信息(如用户名、权限等)存储在会话中,Spring Session 将这些信息存储在 Redis 等外部存储中。
- 问题:当网关认证用户后,安全上下文(
SecurityContext)被创建并存储在会话中,但可能尚未持久化到 Redis。 - 需求:下游服务需要访问用户的认证信息来进行授权检查。
- 解决:
SaveSession确保安全上下文在转发到下游服务之前已保存到 Redis,下游服务可以从 Redis 中读取到正确的认证信息。- 配合
SecureHeaders或其他安全过滤器使用,确保整个安全链路的完整性
- 配合
场景 3:防止会话丢失(高并发场景)
- 背景:在高并发场景下,多个请求可能同时修改同一个会话。
- 问题:如果会话保存操作不是在转发前显式执行,可能会出现竞态条件,导致某些修改丢失。
- 解决:
SaveSession在转发前强制保存,确保当前请求的会话修改不会被后续请求覆盖。- 顺序:请求 A 修改会话 →
SaveSession保存 → 转发 → 请求 B 修改会话 →SaveSession保存 → 转发 - 这样可以保证每个请求的修改都被正确保存,不会相互覆盖
- 顺序:请求 A 修改会话 →
场景 4:会话生命周期管理
- 背景:某些业务逻辑需要在请求处理的不同阶段修改会话属性。
- 需求:确保会话在每次修改后都能及时持久化,避免因应用崩溃或重启导致会话数据丢失。
- 解决:在关键路由上使用
SaveSession,确保会话数据的及时持久化。- 例如:在用户登录、权限变更、购物车更新等关键操作后,立即保存会话