目前系统使用的网关是Spring Cloud Gateway,并且加入了Spring Security来保护系统。 用户认证是基于jwt来认证,因此没用使用session。
但是经过测试发现,当请求的cookie中有session时,服务端响应的set-cookie 中也有session字段,并且session是空值,因此我们需要禁用session,避免返回空值。
1.如果是基于springmvc的服务,那么禁用session 可以在配置类WebSecurityConfigurerAdapter的子类中增加session相关的配置
@Override
protected void configure(HttpSecurity http) throws Exception {
//设置session为无状态模式
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.antMatchers("/**").permitAll();
}
2.但是Spring Cloud Gateway 是基于spring webflux 没有上面的WebSecurityConfigurerAdapter配置类,经过翻看代码发现,在默认的ServerWebExchange的实现类DefaultServerWebExchange中有关于session的配置
DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext) {
Assert.notNull(request, "'request' is required");
Assert.notNull(response, "'response' is required");
Assert.notNull(sessionManager, "'sessionManager' is required");
Assert.notNull(codecConfigurer, "'codecConfigurer' is required");
Assert.notNull(localeContextResolver, "'localeContextResolver' is required");
// Initialize before first call to getLogPrefix()
this.attributes.put(ServerWebExchange.LOG_ID_ATTRIBUTE, request.getId());
this.request = request;
this.response = response;
//session 管理 默认的为DefaultWebSessionManager 使用的是InMemoryWebSessionStore
this.sessionMono = sessionManager.getSession(this).cache();
this.localeContextResolver = localeContextResolver;
this.formDataMono = initFormData(request, codecConfigurer, getLogPrefix());
this.multipartDataMono = initMultipartData(request, codecConfigurer, getLogPrefix());
this.applicationContext = applicationContext;
}
基于此可以在系统中 注入一个WebSessionManager,此WebSessionManager初始化为DefaultWebSessionManager,并且调用setSessionIdResolver方法。
设置的SessionIdResolver为CookieWebSessionIdResolver的子类,置空session过期的方法expireSession
此时相当于session过期之后不做任何处理,因此也不会有set-cookie的响应
,如下
@Bean
public WebSessionManager webSessionManager() {
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
defaultWebSessionManager.setSessionIdResolver(new CookieWebSessionIdResolver(){
@Override
public void expireSession(ServerWebExchange exchange) {
//session 过期不做任何处理
}
});
return defaultWebSessionManager;
}
此时DefaultServerWebExchange中的sessionManager 就被替换成我们自定义的返回空的session的对象。此时不对session做任何处理。最终返回出去的set-cookie 中就没有session 相关的内容。