如何在不配置策略显式的情况下获取对SessionAuthenticationStrategy的引用?

Ral*_*lph 9 java spring spring-security

在基于Spring Security 3.2的应用程序中,我有一个显式配置UsernamePasswordAuthenticationFilter,需要引用sessionAuthenticationStrategy(以便调用.onAuthentication).*

sessionAuthenticationStrategy<security:http>(HttpSecurityBeanDefinitionParser)创建的默认值.

我的问题:如何在SessionAuthenticationStrategy不配置完整的SessionAuthenticationStrategyexplicite 的情况下获得对引用的引用,以便我可以在XML配置中注入此引用?

<security:http auto-config="false" use-expressions="true"
    entry-point-ref="loginUrlAuthenticationEntryPoint" 
    access-decision-manager-ref="httpAccessDecisionManager">
    ...
    <security:custom-filter
             ref="usernamePasswordAuthenticationFilter"
             position="FORM_LOGIN_FILTER"/>
    ...
</security:http>

...

<bean id="usernamePasswordAuthenticationFilter"
    class=" o.s.scurity.web.authentication.UsernamePasswordAuthenticationFilter">

   <property name="sessionAuthenticationStrategy" ref="????">   <!-- ?? ->
   ...
</bean>
Run Code Online (Sandbox Code Playgroud)

*我的真实UsernamePasswordAuthenticationFilter是一个定制的子类,但这对于这个问题无关紧要

Ral*_*lph 6

我已经看过HttpSecurityBeanDefinitionParser(和HttpConfigurationBuilder.createSessionManagementFilters())那个负责解析security:http标签和创建SessionAuthenticationStrategybean的类.

因此我知道Spring Security 3.2.5.RELEASE创建(在我的配置中)一个CompositeSessionAuthenticationStrategybean并将其用作会话策略.这个bean将获得默认名称:org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy#0

所以我目前的解决方法是通过它的名称引用这个bean:

<bean id="usernamePasswordAuthenticationFilter"
     class=" o.s.scurity.web.authentication.UsernamePasswordAuthenticationFilter">

    <property name="sessionAuthenticationStrategy">
        <ref
           bean="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy#0"/>                
    </property>
    ...
 </bean>
Run Code Online (Sandbox Code Playgroud)

此解决方法有一些严重的限制:

  • 当更新版本的spring security以另一种方式工作(创建另一个bean)时,它将失败.
  • 当有另一个CompositeSessionAuthenticationStrategy名称被创建时,ReaderContext.generateBeanName这种方法可能会失败,因为#0可能会变成#1(取决于创建bean的顺序)


Ser*_*sta 4

恐怕没有明显的方法来获得它。

但是 Spring-Security 参考手册中的所有示例在这一点上都是一致的:您甚至不应该想要得到它:所有都显示SessionAuthenticationStrategy在 中显式注入UserNamePasswordAuthenticationFilter,如果适用的话在SessionManagementFilter.

根据这两个类的javadoc,默认值SessionAuthenticationStrategy是:

  • SessionFixationProtectionStrategy对于 Servlet < 3.1
  • ChangeSessionIdAuthenticationStrategy适用于 Servlet 3.1+

因此,正确的方法是创建一个实现SessionAuthenticationStrategy上述默认值之一的 bean,或者如果您有特殊需求,则创建另一个实现,并在需要的地方使用它。

当然,总是可以使用反射来访问 Spring 安全性实现类的私有成员,但您知道这很糟糕,并且在下一版本的 Spring 安全性中存在被破坏的高风险。