首页 文章

Spring 季 Session 和CORS

提问于
浏览
2

我正在为我的REST API使用Spring会话和Spring安全性,但是当我通过一个简单的过滤器启用CORS时遇到了问题 .

  • 如果我使用http代理的相对URI(在客户端应用程序中将 Map 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堆栈,包括Spring 4.1.4.RELEASE,Spring Security 4,Spring Session 1.0.0.RELEASE等

Spring会话配置:

@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初始化程序(@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,
                "/*"
        );

I have resolved the problem. 我将 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);
        }
    }

}

Thus the doFilter only executes in none OPTIONS method. 该解决方案暂时克服了这一障碍 . 我认为这可能是一个与Spring Session相关的bug .

2 回答

  • 0

    CORS filter需要知道允许的请求标头列表中的Spring Session标头 . HeaderHttpSessionStrategy将其定义为"x-auth-token"但可以更改 . 请注意,以"x-"开头的任何标头都被视为特定于应用程序,这是一个告诉您需要配置CORS过滤器以允许它的标志 .

  • 0

    可以在您的请求方法帮助中添加@CrossOrigin吗?如下:

    @GetMapping("/path")
        @CrossOrigin
        public String detail(@PathVariable("id") Integer activityId){
    
    
            return "";
        }
    

相关问题