spring - 如何在 Spring webflux 应用程序中将 Spring WebSessionIdResolver 与 Spring Security 5 结合使用?

标签 spring spring-security reactive-programming spring-session spring-webflux

目前我正在体验新的 Spring 响应式(Reactive)堆栈,并希望使用 Spring Session 2.0 中的响应式(Reactive)功能。

在传统的Servlet方法中,Spring Session提供了一个HttpSessionStrategy来检测cookie或请求 header 中的 session 。使用 HeaderHttpSessionStrategy 可以轻松地为 RESTful API 实现类似 token 的身份验证(默认名称为 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();
}

一个测试休息 Controller 文件,它返回当前的 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时,响应 header 中没有 session 信息。

curl -v -u "user:password" http://localhost:8080/sessionId

我在查询结果中获取了 session id并将其放入请求 header 中以访问 protected 资源,并得到了401。

curl -v -X POST -H "X-SESSION-ID:xxxx" http://localhost:8080/posts

更新:可以找到工作示例 here .

最佳答案

Spring框架的spring-web模块默认使用它的CookieWebSessionIdResolver,它是基于cookie的。如果您创建 HeaderWebSessionIdResolver 类型的替代 bean,Spring Session 将自动选取它并切换到基于 header 的策略。

在任一策略中,它都适合读取传入的 ServerExchange header ,并查找 session ID,无论是读取 Cookie header 还是 SESSION http header 。

这些策略还会创建响应 header ,无论是客户端(Web 浏览器或您的代码)填充 Cookie 的 set-cookie 指令,还是为您提供 SESSION header (HeaderWebSessionIdResolver header 名称的默认名称)。

关于spring - 如何在 Spring webflux 应用程序中将 Spring WebSessionIdResolver 与 Spring Security 5 结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46745494/

相关文章:

javascript - Bacon.js 总线的 RxJS 等价物是什么?

reactive-programming - FRP本质 : functional reactive programming as programming with (discrete) differential equations?

java - Spring 安全: can't clear authentication object

java - Spring 3 - 如何在传递额外的请求参数时抛出异常

spring - 库 jar 可以从 Spring Cloud Config Server 读取属性吗?

spring-security - Spring Security - 自定义 JWT 错误消息

spring - Grails Spring社交插件构建错误

grails - Spring Security和Grails-自定义URL

java - spring和spring security配置求助,找不到bean

transactions - 以 react 方式处理事务资源