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

时间:2014-10-17 17:01:47

标签: java spring spring-security

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

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

我的问题:如果没有配置完整的SessionAuthenticationStrategy explicite,我怎样才能获得对SessionAuthenticationStrategy的引用,以便我可以在XML配置中注入此引用? < / p>

<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>

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

4 个答案:

答案 0 :(得分:6)

我查看了HttpSecurityBeanDefinitionParser(以及HttpConfigurationBuilder.createSessionManagementFilters()),它是负责解析security:http标记和创建SessionAuthenticationStrategy bean的类。< / p>

因此我知道Spring Security 3.2.5.RELEASE创建(在我的配置中)一个CompositeSessionAuthenticationStrategy bean并将其用作会话策略。该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>

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

  • 当更新版本的spring security以其他方式工作(创建另一个bean)时,它将失败。
  • 如果其他CompositeSessionAuthenticationStrategy名称是使用ReaderContext.generateBeanName创建的,则此方法可能会失败,因为#0可能会变为#1(取决于其中的顺序)豆子被创造了)

答案 1 :(得分:4)

我担心没有明显的方法可以获得它。

但是Spring-Security参考手册中的所有示例都是连贯的:你甚至不应该想要它:所有在SessionAuthenticationStrategy中都显示一个明确的UserNamePasswordAuthenticationFilter,如果合适的话{ {1}}。

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

  • SessionAuthenticationStrategy for Servlet&lt; 3.1
  • SessionFixationProtectionStrategy for Servlet 3.1 +

所以正确的方法是创建一个实现ChangeSessionIdAuthenticationStrategy上述默认值之一的bean,或者如果您有特殊需求,可以使用其他实现,并在需要的地方使用它。

当然,总是可以使用反射来访问Spring安全实现类的私有成员,但是你知道它是 bad 并且在下一版Spring安全版中被破坏的风险很高

答案 2 :(得分:3)

展开Ralph's answer,您可以使用FactoryBean获取对AuthenticationStrategy的引用。

public class SessionAuthenticationStrategyFactoryBean implements BeanFactoryAware, FactoryBean<SessionAuthenticationStrategy> {

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public SessionAuthenticationStrategy getObject() throws Exception {
        final CompositeSessionAuthenticationStrategy sas = beanFactory.getBean(CompositeSessionAuthenticationStrategy.class);
        return sas;
    }

    @Override
    public Class<?> getObjectType() {
        return SessionAuthenticationStrategy.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

...并在XML配置上提供它:

<bean id="sas" class="com.example.SessionAuthenticationStrategyFactoryBean" />

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

   <property name="sessionAuthenticationStrategy" ref="sas">
   ...
</bean>

答案 3 :(得分:2)

使用JavaConfig时(我恐怕不是你的情况)你可以通过

获得参考
        http.getConfigurer(SessionManagementConfigurer.class).init(http);
        http.getSharedObject(SessionAuthenticationStrategy.class);