2013-06-03 116 views
2

我正在使用spring-security 3.1。Custom ConcurrentSessionControlStrategy

我必須以最大會話數由用戶指定的方式實現會話併發策略。下面是我做的:

編碼擴展 org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy類和推翻的方法

protected int getMaximumSessionsForThisUser(Authentication authentication)

我使用了命名空間配置它配置:

<security:http> 
    ... 
    <security:session-management session-authentication-strategy-ref="mySessionAuthenticationStrategy"/> 
    ... 
</security:http> 

<bean id="mySessionAuthenticationStrategy" class="foo.bar.MySessionAuthenticationStrategy"> 
    <constructor-arg ref="sessionRegistry"/> 
</bean> 

<bean id="sessionRegistry" 
     class="org.springframework.security.core.session.SessionRegistryImpl" /> 

問題是「MySessionAuthenticationStrategy」從不會被調用:(

我在春天API挖地看到,在SessionManagementFilter以下行(70)是假的(防止任何SessionAuthenticationStrategy被調用):

if (!securityContextRepository.containsContext(request)) 

這是爲什麼? 我閱讀他們建議在UsernamePasswordAuthenticationFilter中設置會話身份驗證策略的文檔,但由於我將表單登錄和SAML登錄以及驗證身份驗證令牌的機制(3種不同的身份驗證機制)相結合,因此它不適合我。

你們中的任何人都可以提供幫助嗎?

回答

3

簡短的回答(這是猜測):這個問題可能是你的權威性預過濾器(或其它非表單登錄過濾器),而本身調用SessionAuthenticationStrategy首先創建一個會話。

詳細解釋:line you mentioned基本上是檢查請求是否剛剛在過濾器鏈的當前執行過程中驗證,而沒有auth過濾器創建新的會話。該檢查檢查是否存在會話,以及是否已將auth對象保存到會話中。

如果它發現會話和已保存的auth對象,那就意味着什麼都不必做:一切已經被安排在關於認證和會話管理的任何其他過濾器中,或者在處理之前的請求之前被相同的SessionManagementFilter在同一屆會議上。

另一種情況是沒有創建會話或(非匿名)auth對象尚未保存在現有會話中。只有在這種情況下,SessionManagementFilter纔有責任通過調用SessionAuthenticationStrategy來執行會話管理。

根據您的描述,第二種情況從不會發生,這意味着會話已經創建,並且auth對象已經保存在此執行點。這應該意味着你的自定義驗證過濾器必須創建一個會話,這本身不是問題。但是,一般的規則是,任何創建會話的人都必須先諮詢SessionAuthenticationStrategy本身。如果您的身份驗證篩選器選擇忽略它,則SessionManagementFilter(無法撤消會話創建,即使SessionAuthenticationStrategy已對用戶的身份驗證提出否決權)也無法完成任何操作。

如果出現這種情況,請仔細檢查並嘗試避免在您的預驗證過濾器中創建會話。請注意,會話創建也可以通過SaveToSessionResponseWrapper.saveContext()這種偷偷摸摸的方式發生,例如,重定向。

+0

非常好的解釋,你是對的。我的PreAuthentication過濾器使用一個使用會話的AuthenticationSuccessHandler(創建一個)。謝謝 ! – baraber