1

私は春のセキュリティに取り組んできましたが、すべてうまくいっています。しかし、私はそれがどのように機能するかをデバッグしました。すべてのフィルターは、http 名前空間を介して springsecurityfilterchain 用に構成されます。それらの 1 つは、認証を提供するための認証フィルターです。私が見つけたのは、新しいログイン要求が来ると(以前のセッションがない)認証フィルターが呼び出されますが、すでにログインしているユーザー、つまり既存のセッションに対して要求が来ると、認証フィルターは呼び出されません。「springsecurity」がすでにログインしているリクエストに対してこの認証をスキップする場所と方法を見つけることができませんでした。これを理解するのを手伝ってください。

ありがとう

4

5 に答える 5

0

SessionManagementFilterがこれを処理すると思います:

        if (!securityContextRepository.containsContext(request)) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null && !authenticationTrustResolver.isAnonymous(authentication)) {
         // The user has been authenticated during the current request, so call the session strategy
            try {
                sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
            } catch (SessionAuthenticationException e) {
                // The session strategy can reject the authentication
                logger.debug("SessionAuthenticationStrategy rejected the authentication object", e);
                SecurityContextHolder.clearContext();
                failureHandler.onAuthenticationFailure(request, response, e);

                return;
            }
            // Eagerly save the security context to make it available for any possible re-entrant
            // requests which may occur before the current request completes. SEC-1396.
            securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response);
        } else {
         // No security context or authentication present. Check for a session timeout
            if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
                if(logger.isDebugEnabled()) {
                    logger.debug("Requested session ID " + request.getRequestedSessionId() + " is invalid.");
                }

                if (invalidSessionStrategy != null) {
                    invalidSessionStrategy.onInvalidSessionDetected(request, response);
                    return;
                }
            }
        }
    }

もちろん、ここには目に見える以上のものがあります。認証はThreadLocalに保存されます:

Spring Securityでは、リクエスト間にSecurityContextを格納する責任は、SecurityContextPersistenceFilterにあります。これは、デフォルトで、HTTPリクエスト間のHttpSession属性としてコンテキストを格納します。リクエストごとにコンテキストをSecurityContextHolderに復元し、重要なことに、リクエストが完了するとSecurityContextHolderをクリアします。セキュリティ上の理由から、HttpSessionを直接操作しないでください。そうする理由はまったくありません。代わりに、常にSecurityContextHolderを使用してください。

したがって、コンテキストデータをロードする(そして後で消去する)のはSecurityContextPersistenceFilterの責任であり、フィルターチェーンの他のモジュールがこのデータに基づいて決定を下します。(たとえば、usermanagerサービスを介して認証をスキップまたは実行します)

私はSpringSecurity開発者ではないので、この情報は知識に基づいた推測としてのみ使用してください:)

于 2012-06-27T09:26:18.130 に答える
0

次の 3 つの組み合わせで処理されFiltersます。

于 2012-07-05T00:54:57.833 に答える
0

httpSessionIntegrationFilterこれを処理します。同じユーザーからのリクエスト間のセッションを維持する責任があります。

于 2012-07-12T10:01:38.023 に答える
0

わかりました質問はまだ実際にある可能性があるので、答えようとします:

私自身の調査によると、「スキップ」しているようには見えません。

まず、スプリングがフィルター チェーンを生成します。スプリング ブートを使用する場合は、デバッグを有効にするだけで、ブート ログでフィルター チェーン全体を確認できます。

各リクエストはこのチェーンを通過します。「configure」メソッドと HttpSecurity オブジェクトで何を構成してもかまいません。だからあなたのフレーズ

私が見つけたのは、新しいログイン要求が来ると(以前のセッションがない)認証フィルターが呼び出されるが、すでにログインしているユーザー、つまり既存のセッションに対して要求が来ると、認証フィルターは呼び出されないことです

本当ではありません。認証フィルターが呼び出されますが、doFilter 内にチェック要求が存在し、URL がログイン用でない場合、フィルターは doFilter を呼び出して「戻ります」。例: LoginPage フィルターを "/login POST" に構成しました。POST リクエストを /login に異なる資格情報で 1 つずつ送信すると、アプリはセッションを新しいユーザーに書き換えます。したがって、ユーザーにそれを許可したくない場合は、フィルターといくつかのロジックをオーバーライドして、ユーザーがログインしているかどうかをセッションをチェックし、doFilter を呼び出すだけです。

于 2018-05-14T16:00:00.153 に答える
0

保護されたオブジェクトに対して要求が行われると、SessionManagementFilter は SecurityContextRepository を調べます。そのコンテンツが SecurityContextHolder と一致する場合、そのユーザーは以前に認証されていると見なされます (remember-me または pre-authentication など)。

リポジトリにセキュリティ コンテキストが含まれている場合、このフィルタは何もしません。

何もなく、ThreadLocal に認証オブジェクトが含まれている場合、以前のフィルターが何らかの方法でこのユーザーを認証したと想定します。

于 2012-07-09T08:03:02.407 に答える