2014-10-17 4 views
6

In einem Spring Security 3.2-basierte Anwendung habe ich eine explizite UsernamePasswordAuthenticationFilter, konfiguriert, die einen Verweis auf die sessionAuthenticationStrategy müssen (um .onAuthentication aufzurufen). *Wie bekomme ich einen Verweis auf SessionAuthenticationStrategy, ohne die Strategie explizit zu konfigurieren?

Die sessionAuthenticationStrategy ist die Standard erstellt ein von <security:http> (HttpSecurityBeanDefinitionParser).

Meine Frage: Wie kann ich einen Verweis auf die SessionAuthenticationStrategy ohne Konfiguration der vollständigen SessionAuthenticationStrategy Explicite erhalten, so dass ich diese Referenz in XML-Konfiguration injizieren kann?

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

* meine wirkliche UsernamePasswordAuthenticationFilter ist eine maßgeschneiderte Unterklasse, aber das sollte nicht für diese Frage wichtig

+0

ich Referenzierung diese Frage ein Problem eröffnet. https://github.com/spring-projects/spring-security/issues/3995 – mhnagaoka

Antwort

3

Ich fürchte, es gibt keine offensichtliche Möglichkeit, es zu bekommen.

Aber alle Beispiele in Spring-Sicherheitsreferenzhandbuch sind auf dem kohärenten: Sie sollten nicht einmal erhalten mögen: Sie alle zeigen eine explizites SessionAuthenticationStrategy in den UserNamePasswordAuthenticationFilter injizierte und gegebenenfalls in SessionManagementFilter.

Nach dem javadocs dieser zwei Klassen, die Standard-SessionAuthenticationStrategy sind:

  • SessionFixationProtectionStrategy für Servlets < 3.1
  • ChangeSessionIdAuthenticationStrategy für

3.1+ Servlets So ist die richtige Art und Weise zu erstellen ist eine Bean, die SessionAuthenticationStrategy entweder einen der obigen Standardwerte oder eine andere Implementierung implementiert, wenn Sie spezielle Anforderungen haben, und diese verwenden, wo immer Sie dies benötigen.

Natürlich ist es immer möglich, Reflektion zu verwenden private Mitglieder von Spring Security Implementierungsklassen zugreifen, aber Sie wissen, es ist schlecht und kommt mit einem hohen Risiko von auf nächste Version von Spring Sicherheit gebrochen zu werden.

3

Ich habe einen Blick auf den HttpSecurityBeanDefinitionParser habe (und die HttpConfigurationBuilder.createSessionManagementFilters()), die die Klasse verantwortlich zu analysieren, um den security:http-Tag ist und von SessionAuthenticationStrategy Bohne zu schaffen.

Daher weiß ich, dass Spring Security 3.2.5.RELEASE (in meiner Konfiguration) eine CompositeSessionAuthenticationStrategy Bean erstellen und diese als Sitzungsstrategie verwendet. Diese Bean wird den Standardnamen erhalten: org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy#0

Also meine aktuelle Problemumgehung ist ein Verweis auf diese Bohne haben, durch seinen Namen:

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

Diese Problemumgehung hat einige gravierende Einschränkungen:

  • Wenn eine neuere Version der Federsicherheit auf eine andere Weise funktioniert (Erstellen einer anderen Bean), wird sie fehlschlagen.
  • , wenn es ein anderer CompositeSessionAuthenticationStrategy das ist Name mit ReaderContext.generateBeanName dann kann dieser Ansatz geschaffen wird, scheitern, weil die #0 vielleicht #1 werden (abhängig von der Reihenfolge, in der die Bohnen erstellt werden)
1

Wenn mit JavaConfig arbeiten (ich fürchte, ist nicht Ihr Fall) Sie, indem Sie

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

Aufbauend auf Ralph's answer einen Verweis bekommen können, können Sie eine FactoryBean verwenden, um einen Verweis auf die AuthenticationStrategy zu erhalten.

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

... und es auf Sie XML-Konfiguration verfügbar machen:

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

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

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