Spring security 自定义ConcurrentSessionControl策略

Spring security 自定义ConcurrentSessionControl策略,spring-security,Spring Security,我使用的是SpringSecurity3.1 我必须以一种由用户指定最大会话数的方式实现会话并发策略。以下是我所做的: 编写了一个扩展类的代码 org.springframework.security.web.authentication.session.ConcurrentSessionControl策略并重写该方法 protected int getMaximumSessionsForThisUser(身份验证) 我使用命名空间配置对其进行了配置: <security:http>

我使用的是SpringSecurity3.1

我必须以一种由用户指定最大会话数的方式实现会话并发策略。以下是我所做的:

编写了一个扩展类的代码 org.springframework.security.web.authentication.session.ConcurrentSessionControl策略并重写该方法

protected int getMaximumSessionsForThisUser(身份验证)

我使用命名空间配置对其进行了配置:

<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" />
为什么呢? 我阅读了文档,其中他们建议在
UsernamePasswordAuthenticationFilter
中设置会话身份验证策略,但这不是我的选项,因为我将表单登录与SAML登录以及
预身份验证
验证身份验证令牌的机制(3种不同的身份验证机制)相结合

任何人都可以提供帮助?

简短回答(这是一个猜测):问题可能是您的预验证筛选器(或其他非表单登录筛选器)创建会话时本身没有首先调用
SessionAuthenticationStrategy

详细说明:基本上是检查请求是否在筛选器链的当前执行中刚刚经过身份验证,而没有auth筛选器创建新会话。该检查检查是否存在会话,以及是否已将身份验证对象保存到会话中

如果它找到了会话和保存的auth对象,则意味着无需执行任何操作:在处理同一会话中先前的请求期间,已通过其他筛选器或相同的
SessionManagementFilter
安排了有关身份验证和会话管理的所有内容

另一种情况是,尚未创建会话或(非匿名)身份验证对象尚未保存在现有会话中。只有在这种情况下,
SessionManagementFilter
才有责任通过调用
SessionAuthenticationStrategy
来实际执行会话管理

根据您的描述,第二种情况从未发生过,这意味着会话已经创建,并且auth对象在执行时已经保存。这意味着您的自定义身份验证筛选器必须已创建会话,这本身不是问题。但是,一般规则是,任何创建会话的人都必须首先查阅
SessionAuthenticationStrategy
本身。如果您的身份验证筛选器选择忽略它,
SessionManagementFilter
无法执行任何操作(即使
SessionAuthenticationStrategy
对用户的身份验证提出否决,它也无法撤消会话创建)


仔细检查是否存在这种情况,并尝试避免在预验证筛选器中创建会话。请注意,会话创建也可能以一种隐蔽的方式发生,例如在重定向时被调用。

非常好的解释,你是对的。我的预验证筛选器使用使用会话(创建会话)的AuthenticationSuccessHandler。非常感谢。
if (!securityContextRepository.containsContext(request))