2

REST API に Spring セッションと Spring セキュリティを使用していますが、単純なフィルターを介して CORS を有効にすると問題が発生しました。

  1. http プロキシで相対 URI を使用した場合 (クライアント アプリで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 追加フィルター チェーンの 10 の位置 1 で。発射フィルター: 'WebAsyncManagerIntegrationFilter'
    2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.FilterChainProxy - /api/mgt/appupdates 追加のフィルター チェーンの 10 の位置 2。起動フィルター: 'SecurityContextPersistenceFilter'
    2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession は現在存在しません
    2015-02-11 10:46:57,745 [http-nio-8080-exec-29] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession から SecurityContext を利用できませんでした: null。新しいものが作成されます。

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 は OPTIONS メソッド以外でのみ実行されます。このソリューションは、一時的にこの障壁を克服します。これは、Spring Session 関連のバグである可能性があると思います。

4

2 に答える 2

0

CORS フィルターは、許可されたリクエスト ヘッダーのリスト内の Spring Session ヘッダーについて知る必要があります。HeaderHttpSessionStrategy はこれを「x-auth-token」と定義していますが、変更することができます。「x-」で始まるヘッダーはアプリケーション固有のものとして扱われることに注意してください。これを許可するには、CORS フィルターを構成する必要があります。

于 2015-03-16T14:16:06.223 に答える