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

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

sessionAuthenticationStrategyHttpSecurityBeanDefinitionParser )创建的默认值。

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

  ...  ...  ...   

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

但是Spring-Security参考手册中的所有示例都是连贯的:您甚至不应该想要它:所有显示在UserNamePasswordAuthenticationFilter注入的显式SessionAuthenticationStrategy以及SessionManagementFilter是否合适。

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

  • Servlet的SessionFixationProtectionStrategy <3.1
  • Servlet 3.1+的ChangeSessionIdAuthenticationStrategy

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

当然,总是可以使用reflection来访问Spring安全实现类的私有成员,但是你知道它很糟糕,并且很有可能在下一个Spring安全版本上被破解。

我已经看过HttpSecurityBeanDefinitionParser (以及HttpConfigurationBuilder.createSessionManagementFilters() ),它是负责解析security:http标签和创建SessionAuthenticationStrategy bean的类。

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

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

     ...  

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

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

使用JavaConfig时(我担心不是你的情况)你可以通过这样做获得参考

  http.getConfigurer(SessionManagementConfigurer.class).init(http); http.getSharedObject(SessionAuthenticationStrategy.class); 

扩展Ralph的答案 ,您可以使用FactoryBean来获取AuthenticationStrategy的引用。

 public class SessionAuthenticationStrategyFactoryBean implements BeanFactoryAware, FactoryBean { 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配置上使其可用:

    ...