2

私の企業イントラネット アプリケーションは、事前認証シナリオを使用しています。SpringSecurity フィルター チェーンの前に 2 つのフィルターが挿入されています。1つ目は株式会社が提供するフィルターです。すべてのログイン、パスワードなどを処理し、ユーザーを認識すると、Cookie のプリンシパルに認証データを入れます。2 番目はこれをすべて変換し、UserDetails オブジェクトと認証トークンを作成して SecurityContextHolder に配置します。

SecurityContextHolder.getContext().setAuthentication(token);
logger.debug("Auth token submitted");

私のログは、これが起こっていることを確認しています:

2015-09-30 13:02:08,998 DEBUG c.a.v.c.s.MyPreauthFilter [http-bio-8081-exec-63] Auth token submitted

数ミリ秒後、Spring Security フィルター チェーンが入ってきて、次のことを行います。

2015-09-30 13:02:09,002 DEBUG o.s.s.w.FilterChainProxy [http-bio-8081-exec-63] /index.html at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-09-30 13:02:09,007 DEBUG o.s.s.w.FilterChainProxy [http-bio-8081-exec-63] /index.html at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-09-30 13:02:09,008 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository [http-bio-8081-exec-63] HttpSession returned null object for SPRING_SECURITY_CONTEXT
2015-09-30 13:02:09,008 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository [http-bio-8081-exec-63] No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@721c23ce. A new one will be created.

基本的に、HttpSessionSecurityContextRespositoryは (フィルタ チェーンの一部) によって呼び出されSecurityContextPersistenceFilter、SESSION でセキュリティ コンテキストをチェックしますが、セッションでセキュリティ コンテキストが見つからず、SecurityContextHolder に配置したばかりのコンテキストを新しい空のコンテキストに置き換え、認証が行われます。数行下の失敗。

2015-09-30 13:02:09,024 DEBUG o.s.s.w.a.ExceptionTranslationFilter [http-bio-8081-exec-63] Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied

Spring のドキュメントHttpSessionSecurityContextRespositoryでは .

代わりに、Spring Security Filter チェーンの後に 2 番目のフィルターを挿入してみることができるかもしれないと考えましたが、それは役に立ちませんでした。FilterSecurityInterceptor (チェーンの 11 番目のアイテム) は、私の 2 番目のフィルターがチェーンの前にあったときと同じように、私の認証を拒否しました。

セッションで SecurityContext を保存するのは何ですか? また、設定したばかりのセキュリティ コンテキストを一掃する際に SecurityContextPersistenceFilter の動作を無効にするにはどうすればよいですか?

4

1 に答える 1

0

回避策を開発しました。必要ないはずですが、うまくいくようです。

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException 
{

...
    PreAuthenticatedAuthenticationToken token = ...


    logger.debug("Auth token placed in SecurityContext: \n" + token);
    SecurityContextHolder.getContext().setAuthentication(token);

    // make sure the session has a SecurityContext at this point
    ensureSessionHasSecurityContext(hreq);

    super.doFilter(request,response, chain);

    logger.debug("Auth token after rest of chain: \n" + SecurityContextHolder.getContext()
            .getAuthentication());

}

private void ensureSessionHasSecurityContext(HttpServletRequest hreq) {
    HttpSession session = hreq.getSession(false);
    Object securityContext = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
    if (securityContext == null) {
        logger.debug("no SecurityContext found in session, inserting ours");
        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
    }

}

問題があると思われる場合は、このソリューションを暴いてください。しかし、フィルタ チェーンが新しい認証を無効にしないことを保証するために考えられる唯一の方法は、必要なときに、事前認証フィルタがその役割を果たした直後ですが、Spring フィルタ チェーンが引き継ぐ前です。

于 2015-10-01T02:52:31.967 に答える