私があなたの要件を正しく理解していれば、アプリケーションへの 2 つの異なるエントリ ポイント (ログイン ページ) が必要になります。
- まだアクティブ化されていないユーザーのアクティブ化 (最初のログイン) 用の 1 つ。
- アクティブなユーザー向けの別の「通常の」もの。
問題は、認証ロジックがコンテキストに依存し、上記のどのページが認証を開始したかを認識する必要があることです。ただし、フレームワークはそのようなまれなユースケース用に設計されていないため、認証プロバイダーは、ログインフォームが実際に送信された URL については知りません。
解決する必要があるのは、その情報に従って認証要求を処理する認証プロバイダーにコンテキスト情報をリレーすることです (つまり、url1 からログインしているアクティブでないユーザーのみを認証し、url2からログインしているアクティブなユーザーのみを認証します)。これを実現するには何百もの方法が考えられますが、考えられる解決策の 1 つは、2 つの異なる URL に送信された認証リクエストをインターセプトする 2 つの異なる認証フィルターを配置することです。詳細は以下のとおりです。
WebAuthenticationDetailsSource
認証要求の URI を格納および公開する既存のandの独自のカスタム バージョンをWebAuthenticationDetails
(できれば後者をサブクラス化することによって) 作成します。(これは、認証プロバイダーが条件付きロジックを実装できるコンテキスト情報になります。)
- の 2 つの異なるインスタンスを設定
UsernamePasswordAuthenticationFilter
し、フィルタ チェーンに挿入します。filterProcessesUrl
それぞれの属性を/j_spring_security_check_active_user
およびに設定し、上記で作成したカスタムを両方に/j_spring_security_check_nonactive_user
挿入します。AuthenticationDetailsSource
DaoAuthenticationProvider.additionalAuthenticationChecks()
次の方法でサブクラスを
オーバーライドします。
- 上記で作成したオブジェクトに保存されている URI を取得し
WebAuthenticationDetails
ます ( 経由でアクセスできますauthentication.getDetails()
) 。
- ユーザーが URI に従ってアクティブ/非アクティブであることをアサートし
AccountStatusException
、アサーションが失敗した場合にスローします。
- アサーションが成功した場合は、スーパークラスに委譲することを忘れないでください。
- 投稿の冒頭で説明した 2 つの異なるログイン ページを作成し、ログイン フォームが資格情報をそれぞれの URL (
/j_spring_security_check_nonactive_user
vs. /j_spring_security_check_active_user
) に送信するようにします。