在基于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
是一个自定义的子类,但这对于这个问题无关紧要
答案 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>
此解决方法有一些严重的限制:
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);