Весенняя сессия и CORS

Я использую сеанс Spring и безопасность Spring для своего REST API, но столкнулся с проблемой, когда включил CORS с помощью простого фильтра.

  1. Если я использовал относительный URI через http-прокси (сопоставьте http://xxxx/api с / api в клиентском приложении), он работает хорошо.
  2. Если я использовал полный 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 и т. Д.

Конфигурация весенней сессии:

 @Configuration
 @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60 * 120 )
 public class RedisHttpSessionConfig {

    @Bean 
    public HttpSessionStrategy httpSessionStrategy(){
        return new HeaderHttpSessionStrategy(); 
    }

 }  

Содержимое класса инициализатора сеанса Http:

@Order(100)
public class RedisHttpSessionApplicationInitializer 
        extends AbstractHttpSessionApplicationInitializer {}

RedisHttpSessionConfig загружен в мой веб-инициализатор (@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 OPTIONS. Это решение временно преодолевает этот барьер. Я думаю, это может быть ошибка, связанная с Spring Session.


person Hantsy    schedule 11.02.2015    source источник
comment
Вы можете добавить в фильтр игнорирование CROS. По умолчанию он блокируется. Можете ли вы убедиться, что попали в фильтр.   -  person java_dude    schedule 13.02.2015


Ответы (2)


фильтр CORS должен знать о заголовке Spring Session. в списке разрешенных заголовков запросов. HeaderHttpSessionStrategy определяет это как «x-auth-token», но его можно изменить. Обратите внимание, что любой заголовок, начинающийся с «x-», рассматривается как специфичный для приложения, это контрольный знак, который вам необходимо настроить фильтр CORS, чтобы разрешить его.

person Peter Steiner    schedule 16.03.2015
comment
Я знаю этот встроенный CORSFilter в Tomcat, а также раньше использовал другие настраиваемые фильтры CORS и Intercepter. Все заработало. Это может быть специфическая проблема Spring Session. Я решил проблему. - person Hantsy; 20.03.2015
comment
Не только разрешено, но и открыто. В противном случае веб-клиент не получит доступ к этому заголовку. Ниже приведен пример для WebMvcConfigurer # addCorsMappings: registry.addMapping (/ **). AllowedOrigins ({asterisk_here}). AllowedMethods ({asterisk_here}). AllowedHeaders (X-Auth-Token) .exposedHeaders (X-Auth-Token); - person Eugene Maysyuk; 08.04.2020

Может ли он добавить @CrossOrigin в справку по методу вашего запроса? как показано ниже:

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


        return "";
    }
person Y.Ido    schedule 02.11.2017