我正在使用 Hazelcast 来存储用户会话。请求通过
SessionRepositoryFilter
,但如果出现错误,则请求将转发到 /error。转发的请求不会通过该过滤器,因此 tomcat 使用新 ID(不是像 Hazelcast 会话 ID 那样的 UUID)创建一个新会话,并使用 set-cookie 标头进行响应,告诉客户端将其会话 ID 更改为新的,错了。当客户端发出下一个请求时,Hazelcast 无法识别 tomcat 会话 ID,因此会响应 401 未经授权。
AbstractFilterRegistrationBean#determineDispatcherTypes
方法 决定 SessionRepositoryFilter
不应该应用于转发的请求,因为它不是 org.springframework.web.filter.OncePerRequestFilter
的实例。相反,它是 org.springframework.session.web.http.OncePerRequestFilter
的实例。我认为这可能是一个错误 - 它们都应该过滤所有调度类型。
如何将
SessionRepositoryFilter
FilterMap
的dispatcherMapping编辑为31,即过滤所有请求?
我可以自己注册过滤器并设置调度类型:
@Bean
public FilterRegistrationBean<SessionRepositoryFilter<? extends Session>> springSessionRepositoryFilterRegistration(
SessionRepositoryFilter<? extends Session> springSessionRepositoryFilter) {
FilterRegistrationBean<SessionRepositoryFilter<? extends Session>> registration =
new FilterRegistrationBean<>(springSessionRepositoryFilter);
registration.setOrder(SessionRepositoryFilter.DEFAULT_ORDER);
// By default, this would only filter on DispatcherType.REQUEST
// because it doesn't extend org.springframework.web.filter.OncePerRequestFilter
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
原来我们的申请排除了
SessionAutoConfiguration
。如果我删除该排除,那么它会导入 SessionRepositoryFilterConfiguration
,这会设置调度类型。
如果出于某种原因你想排除
SessionAutoConfiguration
,你可以让你的 @EnableHazelcastHttpSession
类扩展 AbstractHttpSessionApplicationInitializer
。这也将为您设置调度类型。