【发布时间】:2015-04-11 07:43:27
【问题描述】:
我正在为我的 REST API 使用 Spring session 和 Spring security,但是当我通过一个简单的过滤器启用 CORS 时遇到了问题。
- 如果我通过 http 代理使用相对 URI(在客户端应用程序中将 http://xxxx/api 映射到 /api),效果很好。
- 如果我直接使用完整的URL,我在使用CORS的时候遇到了一个问题,它无法获取会话信息,下面是Spring安全日志。
我正在使用 Spring 堆栈,包括 Spring 4.1.4.RELEASE、Spring Security 4、Spring Session 1.0.0.RELEASE 等
春季会话配置:
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60 * 120 )
public class RedisHttpSessionConfig {
@Bean
public HttpSessionStrategy httpSessionStrategy(){
return new HeaderHttpSessionStrategy();
}
}
Http Session 初始化类内容:
@Order(100)
public class RedisHttpSessionApplicationInitializer
extends AbstractHttpSessionApplicationInitializer {}
RedisHttpSessionConfig 已加载到我的 Web 初始化程序 (@Order(0)) 中。还有另一个 Spring Security 的 Initializer(@Order(200))。
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
private static final Logger log = LoggerFactory.getLogger(SecurityInitializer.class);
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", DelegatingFilterProxy.class);
corsFilter.addMappingForUrlPatterns(
EnumSet.of(
DispatcherType.ERROR,
DispatcherType.REQUEST,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.ASYNC),
false,
"/*"
);
我已经解决了问题。我将 doFilter 方法移到了 else 块中。
@Named("corsFilter")
public class SimpleCorsFilter extends OncePerRequestFilter {
private static final Logger log = LoggerFactory.getLogger(SimpleCorsFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (log.isDebugEnabled()) {
log.debug("call doFilter in SimpleCORSFilter @");
}
response.setHeader("Access-Control-Allow-Origin", "*");
// response.addHeader("X-FRAME-OPTIONS", "SAMEORIGIN");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
if (log.isDebugEnabled()) {
log.debug("do pre flight...");
}
response.setHeader("Access-Control-Allow-Methods", "POST,GET,HEAD,OPTIONS,PUT,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Content-Type,Accept,x-auth-token,x-xsrf-token,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Access-Control-Allow-Origin");
//response.setHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin,x-auth-token");
} else {
filterChain.doFilter(request, response);
}
}
}
因此 doFilter 只在 none OPTIONS 方法中执行。 这个解决方案暂时克服了这个障碍。我认为这可能是与 Spring Session 相关的错误。
【问题讨论】:
-
您可能希望添加有关忽略 CROS 的过滤器。默认情况下它会阻止。你能确定你点击了过滤器吗?
标签: rest spring-mvc spring-security cors spring-session