【问题标题】:How to use Spring WebSessionIdResolver with Spring Security 5 in a Spring webflux application?如何在 Spring webflux 应用程序中使用 Spring WebSessionIdResolver 和 Spring Security 5?
【发布时间】: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找到一个工作示例。

【问题讨论】:

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


    【解决方案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
    猜你喜欢
    • 2018-03-01
    • 2020-03-17
    • 2018-11-03
    • 2018-09-18
    • 2016-03-28
    • 2018-10-31
    • 2017-03-06
    • 2019-05-08
    • 2018-04-12
    相关资源
    最近更新 更多