如何在不配置策略显式的情况下获取对SessionAuthenticationStrategy的引用?
在基于Spring Security 3.2的应用程序中,我有一个显式配置的UsernamePasswordAuthenticationFilter
,它需要对sessionAuthenticationStrategy
的引用(以便调用.onAuthentication
)。*
sessionAuthenticationStrategy
是 (
HttpSecurityBeanDefinitionParser
)创建的默认值。
我的问题: 如何在不配置完整的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配置上使其可用:
...