2

我正在使用弹簧安全 3.1。

我必须以用户指定最大会话数的方式实施会话并发策略。这是我所做的:

编写了一个扩展 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”:(

我在spring api中进行了挖掘,发现以下行(70)SessionManagementFilter是错误的(防止任何SessionAuthenticationStrategy被调用):

if (!securityContextRepository.containsContext(request))

这是为什么 ?我阅读了他们建议在 中设置会话身份验证策略的文档UsernamePasswordAuthenticationFilter,但这对我来说不是一个选项,因为我将表单登录与 SAML 登录以及PreAuthentication验证身份验证令牌的机制(3 种不同的身份验证机制)相结合。

你们中的任何人都可以帮忙吗?

4

1 回答 1

3

简短的回答(这是一个猜测):问题可能是您的预授权过滤器(或其他非表单登录过滤器)创建了一个会话而没有自己调用第SessionAuthenticationStrategy一个。

长解释:您提到的那一行基本上是在过滤器链的当前执行中检查请求是否刚刚通过身份验证,而 auth-filter 没有创建新会话。检查检查是否存在会话,以及是否已将身份验证对象保存到会话中。

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

另一种情况是没有创建会话或(非匿名)身份验证对象尚未保存在现有会话中。只有在这种情况下,SessionManagementFilter通过调用SessionAuthenticationStrategy.

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

仔细检查是否是这种情况,并尽量避免在您的预授权过滤器中创建会话。请注意,会话创建也可以通过SaveToSessionResponseWrapper.saveContext()例如在重定向时被调用以偷偷摸摸的方式发生。

于 2013-06-03T21:02:07.140 回答