2014-10-17 61 views
6

在基於Spring Security的3.2應用程序,我有一個明確的配置UsernamePasswordAuthenticationFilter,需要(爲了調用.onAuthentication)到sessionAuthenticationStrategy的參考。*如何在不明確配置策略的情況下獲取對SessionAuthenticationStrategy的引用?

sessionAuthenticationStrategy<security:http>HttpSecurityBeanDefinitionParser)創建的默認之一。

我的問題:如何在不配置完整的SessionAuthenticationStrategy顯示的情況下獲得對SessionAuthenticationStrategy的引用,以便我可以在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> 

*我真正UsernamePasswordAuthenticationFilter是一個定製的子類,但是這不應該的問題對於這個問題

+0

我打開引用這個問題的問題。 https://github.com/spring-projects/spring-security/issues/3995 – mhnagaoka 2016-07-26 17:50:15

回答

3

恐怕沒有明顯的方式得到它。

但所有Spring的安全參考手冊的例子是上連貫的:你應該甚至不應該想要得到它:所有顯示在UserNamePasswordAuthenticationFilter注入明確SessionAuthenticationStrategy並在適當的SessionManagementFilter

根據這2類的javadoc,默認SessionAuthenticationStrategy是:

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

所以,正確的做法是創建一個實現SessionAuthenticationStrategy以上默認值的bean,或者如果您有特殊需求的其他實現,並在需要的地方使用它。

當然,總是有可能使用反射來訪問Spring安全實現類的私有成員,但你知道它是不好的,並且很有可能在Spring安全性的下一個版本中被破壞。

3

我有看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的引用,它的名字:

<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安全性以另一種方式工作時(創建另一個bean),它將會失敗。
  • 當有其他CompositeSessionAuthenticationStrategy這就是名與ReaderContext.generateBeanName創建那麼這種方法可能會失敗,因爲#0可能成爲#1(取決於這些豆創建順序)
1

當JavaConfig工作(恐怕不是你的情況下),你可以通過做

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

擴展在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> 
相關問題