当前位置: 首页 > 知识库问答 >
问题:

Spring会议和CORS

罗毅
2023-03-14

我的REST API使用Spring会话和Spring Security性,但是当我通过一个简单的过滤器启用CORS时遇到了一个问题。

  1. 如果我通过http代理使用相对URI(映射http://xxxx/api 对于客户端应用程序中的/api),它运行良好。
  2. 如果我直接使用完整的URL,我在使用CORS时遇到了一个问题,它无法获取会话信息,下面是Spring Security日志
    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会话初始值设定项类内容:

@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方法移动到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选项方法中执行。此解决方案暂时克服了此障碍。我认为这可能是一个与Spring会话相关的bug。

共有1个答案

澹台胜
2023-03-14

CORS过滤器需要了解允许请求标头列表中的Spring会话标头。HeaderHttpSessionStrategy将此定义为“x-auth-Token”,但它可以更改。请注意,任何以“x-”开头的标头都被视为特定于应用程序的标头,您需要配置CORS过滤器以允许它。

 类似资料:
  • 我试图在会话范围内创建一个Spring bean: 当我尝试在servlet过滤器中从Application Context获取类时,如下所示: 我收到以下错误: 如果我将范围定义为< code>prototype,就不会有任何问题!如何从applicationContext中检索会话范围的spring bean?

  • OAuth2和Redis不能很好地配合使用。一旦我启用Spring会话,在我经过身份验证(OIDC)并发送回应用程序后,就会创建两个会话ID——一个来自Redis的JSESSIONID,另一个来自Spring Security Oauth。一旦我禁用Redis/Spring会话,一切都很好。 我创建了一个非常小的Maven应用程序,可以从以下网站下载:http://folk.uio.no/erle

  • 会话用于在请求中存储有关用户的信息。 Laravel提供各种驱动程序,如file, cookie, apc, array, Memcached, Redis,和database来处理会话数据。 默认情况下,使用文件驱动程序,因为它是轻量级的。 可以在config/session.php存储的文件中配置会话。 访问会话数据 要访问会话数据,我们需要一个可以通过HTTP请求访问的会话实例。 获取实例后

  • 世界各地的 PHP 社区也会举办一些较大型的区域性或国际性的会议,一些知名的社区成员通常会在这些大型活动中现身演讲,这是一个直接和业内领袖学习的好机会。

  • 我想知道粘性和非粘性会议之间的区别。我从网上读到的: 粘滞:只有一个会话对象将在那里。 非粘性会话:每个服务器节点的会话对象

  • 超大会议,多媒介同时接入 用户可通过手机、PC、平板大规模同时接入如流音视频会议,音质清晰,画面稳定不卡顿。 高清直播,一人主讲多人互动 群组或会议界面发起直播,实现主持人强控场、参与人强互动,一键分享满足企业大型宣讲、培训、讲座等多需求,更有直播回放记录全程。 AI会议助手 会前,AI会议助手智能查看所有参会人日程,避开忙碌时段推荐最合适时间,并统一发出会邀。 聊天中快速发起会议,共享资料 会前