タイトルがわかりにくかったらすいません。詳細はこちら。
バックグラウンド
Spring 3.1.1 と Spring security 3.1.0 を使用する Spring ベースのアプリケーションに取り組んでいます。記述子の関連するフラグメントは次のとおりです。
<security:http auto-config='true'>
<security:intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login login-page='/login' authentication-failure-url="/login?authfailed=true"/>
</security:http>
Web ページの「サインアウト」リンクは、 のような URL を指しますROOT-URL/j_spring_security_logout
。したがって、この URL をクリックすると、ログイン ページ ( login.jsp
) が表示され、正常に再ログインできます。
問題
ユーザーがアプリケーションにログインすると、セッションが期限切れになるまで待ってからサインアウトしようとすると、ログイン ページが表示されます。これで問題ありません。次に、正しい資格情報を入力し、ログイン ボタンをクリックします。現在、彼は、アプリケーションに入る代わりに、ユーザー名とパスワードのフィールドが空の同じログイン ページにリダイレクトされます。ログインの 2 回目の試行は成功します。
重要:これは、ユーザーが以前にログインしていて、セッションの有効期限が切れていて、ログアウトしようとした場合にのみ発生します。たとえば、セッションの有効期限が切れた後にユーザーが他のリンクをクリックした場合は発生しません。この場合、彼はログイン ページにリダイレクトされ、最初の試行から正常にログインできます。
分析
私の調査では、次のことがわかりました。SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess()
ログインページへのリクエストが含まれているために発生したHTTPリダイレクトにより、ログインページに2回到着しrequestCache
ます。セッション属性に「キャッシュされた」リクエストを格納requestCache
するタイプの変数です。HttpSessionRequestCache
"SPRING_SECURITY_SAVED_REQUEST"
通常、このキャッシュは、認証されていないユーザーが認証後にリクエストしたページにリダイレクトするために使用されます。
しかし、これが私たちの場合に起こることです。ユーザーがログインします。その後、彼のセッションは期限切れになります。次に、リンクをクリックしてログアウトします。セッションの有効期限が切れているため、ユーザーは「j_spring_security_logout」にリダイレクトされ、ログイン ページにリダイレクトされます。
この方法のどこかで、ログイン URL が「要求済み」としてキャッシュされるため、ユーザーがログインすると、要求された URL、つまりログイン ページにリダイレクトされます。リダイレクトが発生すると、キャッシュされた URL が削除されるため、無限ループは発生しません。2 回目のログイン試行は成功します。
関連するコードリファレンスは次のとおりです。
ExceptionTranslationFilter.handleSpringSecurityException()
コールsendStartAuthentication()
(168 行目)
これは次のことを行います (183 ~ 184 行目):
SecurityContextHolder.getContext().setAuthentication(null);
requestCache.saveRequest(request, response);
ただし、この時点で要求された URL はログイン ページです。そのため、ログイン ページはキャッシュされます。
この時点で just を呼び出すべきではないようsaveRequest()
です。たとえば、これはSpringフレームワークのバグのようです...
この問題の解決策があり、ここに投稿します。しかし、私の解決策は私にとってはパッチのように見えるので、誰かが「正しい」解決策を知っていることを願っています.
前もって感謝します。