我爲我的REST API使用Spring會話和Spring安全性,但是當我通過一個簡單的過濾器啓用CORS時遇到了問題。春季會議和CORS
- 如果我通過http代理使用相對URI(地圖http://xxxx/api到客戶端應用程序中的/ api),它運行良好。
- 如果我直接使用了完整的URL,在使用CORS時遇到了問題,它無法獲取會話信息,以下是Spring安全日誌。
2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.FilterChainProxy - /api/mgt/appupdates at position 1 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.FilterChainProxy - /api/mgt/appupdates at position 2 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - No HttpSession currently exists 2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
我使用的彈簧組,包括Spring 4.1.4.RELEASE,春季安全4,春季會議1.0.0.RELEASE等
春季會議配置:
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60 * 120)
public class RedisHttpSessionConfig {
@Bean
public HttpSessionStrategy httpSessionStrategy(){
return new HeaderHttpSessionStrategy();
}
}
HTTP會話初始化類內容:
@Order(100)
public class RedisHttpSessionApplicationInitializer
extends AbstractHttpSessionApplicationInitializer {}
RedisHttpSessionConfig加載到我的Web初始化程序(@Order(0))中。還有另一個Spring Security的初始化程序(@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方法轉換爲其他塊。
@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只在沒有OPTIONS方法中執行。這個解決方案暫時克服了這個障礙。我認爲這可能是一個春季會議相關的錯誤。
您可能希望添加一個關於忽略CROS的過濾器。默認情況下它會阻塞。你能確保你打過濾器嗎? – 2015-02-13 08:56:46