2013-06-03 118 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