1

目前我遇到了新的Spring反應堆棧,並且希望在Spring Session 2.0中使用反應式功能。如何在Spring webflux應用程序中使用Spring WebSessionIdResolver和Spring Security 5?

在傳統的Servlet方法中,Spring Session提供了一個HttpSessionStrategy來檢測cookie或請求頭中的會話。對於RESTful API,使用HeaderHttpSessionStrategy很容易實現令牌身份驗證(默認情況下他的名字是X-AUTH-TOKEN)。

Spring 5 core提供了一個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("https://stackoverflow.com/users/{user}/**").access(this::currentUserMatchesPath) 
      .anyExchange().authenticated() 
      .and() 
      .build(); 
} 

測試休息控制器文件,它返回當前會話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

回答

0

Spring框架的spring-web模塊默認使用CookieWebSessionIdResolver,它基於cookie。如果您創建了一個HeaderWebSessionIdResolver類型的替代bean,它將在Spring會話中自動拾取並切換到基於標頭的策略。

在任一策略中,它都適合讀取傳入的ServerExchange標頭,並查找會話標識,無論是讀取Cookie標頭還是SESSION http標頭。

這些策略還會創建響應標頭,無論是爲客戶端(Web瀏覽器還是代碼)填充Cookie的set-cookie指令,還是爲您提供SESSION標頭(HeaderWebSessionIdResolver標頭名稱的缺省名稱) 。

+0

我清楚地知道這一點,並且已經閱讀了關於'WebSessionIdResolver'的測試代碼。但在我的示例中,它與Spring Session和Spring Security一起使用時無法按預期工作。我已經使用'curl'來測試我的API,會話信息沒有附加到響應頭中,也沒有驗證我在後面的步驟中從第一個請求獲得的會話。 – Hantsy

+0

將我的代碼更新到Spring Boot 2.0.0.M6並使其工作,請檢查[示例代碼](https://github.com/hantsy/spring-reactive-sample/tree/master/session-header)。 – Hantsy

相關問題