目前我遇到了新的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 。
我清楚地知道這一點,並且已經閱讀了關於'WebSessionIdResolver'的測試代碼。但在我的示例中,它與Spring Session和Spring Security一起使用時無法按預期工作。我已經使用'curl'來測試我的API,會話信息沒有附加到響應頭中,也沒有驗證我在後面的步驟中從第一個請求獲得的會話。 – Hantsy
將我的代碼更新到Spring Boot 2.0.0.M6並使其工作,請檢查[示例代碼](https://github.com/hantsy/spring-reactive-sample/tree/master/session-header)。 – Hantsy