如果標題不夠清晰,我很抱歉。這裏是細節。會話過期後嘗試註銷導致登錄頁面重定向到登錄頁面
背景
我的工作是使用Spring 3.1.1和Spring 3.1.0安全春基礎的應用。這是我們描述的相關片段:
<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>
網頁上的「註銷」鏈接指向URL像ROOT-URL/j_spring_security_logout
。 因此,點擊這個URL會將我們帶到登錄頁面(login.jsp
),並且可以成功登錄。
問題
如果用戶登錄入到應用程序中,等待,直到會話過期,然後嘗試註銷他到達登錄頁面。這可以。然後他鍵入正確的憑據並單擊登錄按鈕。 現在他被重定向到用戶名和密碼字段爲空而不是輸入到應用程序的相同登錄頁面。第二次嘗試登錄成功。
重要提示:只有當用戶之前登錄,會話過期並且他試圖註銷時纔會發生這種情況。例如,如果用戶在會話過期後單擊其他任何鏈接,則不會發生這種情況。在這種情況下,他被重定向到登錄頁面,並可以從第一次嘗試成功登錄。
分析
我的調查顯示如下。 由於SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess()
引起的HTTP重定向,我們兩次到達登錄頁面,並且發生的原因是requestCache
包含請求登錄頁面。 requestCache
是HttpSessionRequestCache
類型的變量,它在會話屬性"SPRING_SECURITY_SAVED_REQUEST"
中存儲「緩存」請求。
在正常情況下,此緩存用於重定向到未經身份驗證的用戶在身份驗證後請求的頁面。
但是這裏是我們的情況。 用戶登錄。然後他的會話過期了。然後他點擊鏈接註銷。由於會話過期,用戶被重定向到'j_spring_security_logout',將他重定向到登錄頁面。
某處通過這種方式登錄URL被緩存爲「請求」,所以當用戶登錄時,他被重定向到請求的URL,即登錄頁面。發生重定向時,緩存的URL將被刪除,因此不會發生無限循環;第二次嘗試登錄成功。
下面是相關的代碼參考:
ExceptionTranslationFilter.handleSpringSecurityException()
電話(線168)
,做以下兩行(183-184):
SecurityContextHolder.getContext().setAuthentication(null);
requestCache.saveRequest(request, response);
但在請求的URL這一點是登錄頁面。所以,登錄頁面被緩存。
看起來saveRequest()
現在不應該被調用,例如,這味道就像是Spring框架中的一個bug ...
我有解決這個問題的方法,我會在這裏發佈。但是我的解決方案對我來說是一個補丁,所以我希望有人知道「正確」的解決方案。
在此先感謝。
您是否試圖爲' 設置'default-target-url'和'always-use-default-target'' ? –
lschin
還沒有。我會嘗試。 – AlexR
當會話仍然有效並且您單擊「註銷」時會發生嗎? – jddsantaella