如何在 Spring webflux 应用程序中使用 Spring WebSessionIdResolver 和 Spring Security 5?
Posted
技术标签:
【中文标题】如何在 Spring webflux 应用程序中使用 Spring WebSessionIdResolver 和 Spring Security 5?【英文标题】:How to use Spring WebSessionIdResolver with Spring Security 5 in a Spring webflux application? 【发布时间】:2018-03-26 12:13:47 【问题描述】:目前我正在体验新的 Spring 响应式堆栈,并希望在 Spring Session 2.0 中使用响应式功能。
在传统的 Servlet 方法中,Spring Session 提供了一个HttpSessionStrategy
来检测 cookie 或请求标头中的会话。使用HeaderHttpSessionStrategy
为RESTful API 实现类似身份验证的令牌(默认名称为X-AUTH-TOKEN
)很容易。
Spring 5 核心提供了一个 WebSessionIdResolver
来为 Reactive 环境做同样的事情。
但是当它与 Spring Security 一起使用并希望它以传统方式工作时,我无法让它工作。
SessionConfig 文件。
@EnableSpringWebSession
public class SessionConfig
@Bean
public ReactorSessionRepository sessionRepository()
return new MapReactorSessionRepository(new ConcurrentHashMap<>());
@Bean
public WebSessionIdResolver headerWebSessionIdResolver()
HeaderWebSessionIdResolver resolver = new HeaderWebSessionIdResolver();
resolver.setHeaderName("X-SESSION-ID");
return resolver;
部分SecurityConfig。
@EnableWebFluxSecurity
class SecurityConfig
@Bean
SecurityWebFilterChain springWebFilterChain(HttpSecurity http) throws Exception
return http
.authorizeExchange()
.pathMatchers(HttpMethod.GET, "/posts/**").permitAll()
.pathMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN")
//.pathMatchers("/users/user/**").access(this::currentUserMatchesPath)
.anyExchange().authenticated()
.and()
.build();
一个测试rest控制器文件,它返回当前的Session ID。
@RestController
public class SessionRestController
@GetMapping("/sessionId")
public Map<String, String> sessionId(WebSession session)
Map<String, String> map = new HashMap<>();
map.put("id", session.getId());
return map ;
当我启动应用程序并使用 curl 访问 /sessionId 时,响应头中没有会话信息。
curl -v -u "user:password" http://localhost:8080/sessionId
我在查询结果中得到了会话id,放入请求头中访问受保护的资源,得到401。
curl -v -X POST -H "X-SESSION-ID:xxxx" http://localhost:8080/posts
更新:可以在here找到一个工作示例。
【问题讨论】:
【参考方案1】:Spring Framework 的 spring-web 模块默认使用它的 CookieWebSessionIdResolver,它是基于 cookie 的。如果您创建一个 HeaderWebSessionIdResolver 类型的替代 bean,它将被 Spring Session 自动拾取并切换到基于 header 的策略。
在任一策略中,它都适合读取传入的 ServerExchange 标头,并查找会话 ID,无论是读取 Cookie 标头还是 SESSION http 标头。
这些策略还创建响应标头,无论是用于客户端(Web 浏览器或您的代码)填充 Cookie 的 set-cookie 指令,还是为您提供 SESSION 标头(HeaderWebSessionIdResolver 标头名称的默认名称)。
【讨论】:
这点我很清楚,我也看过WebSessionIdResolver
的测试代码。但在我的示例中与 Spring Session 和 Spring Security 一起使用时,它不能按预期工作。我使用curl
来测试我的API,会话信息没有附加到响应头中,也没有验证我在后续步骤中从第一个请求中获得的会话。
将我的代码更新到 Spring Boot 2.0.0.M6 并使其工作,检查sample codes。以上是关于如何在 Spring webflux 应用程序中使用 Spring WebSessionIdResolver 和 Spring Security 5?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring webflux 应用程序中使用 Spring WebSessionIdResolver 和 Spring Security 5?
如何使用 WebFlux 在 Spring Boot 2 中设置登录页面?
如何在 Spring Boot WebFlux 中使用 GET 请求注销
如何使用WebFlux在Spring Boot 2中设置登录页面?