wake-up-neo.com

Konfigurieren Sie RequestContextListener in Spring Boot

Ich habe eine Spring-Boot-Anwendung, die Spring-Security verwendet. Ich habe eine Bean mit einem Anforderungsbereich, die ich automatisch in einen meiner benutzerdefinierten Filter in der Sicherheitsfilterkette einspeisen möchte, aber im Moment funktioniert sie nicht.

Ich verstehe, dass eine Konfiguration erforderlich ist, um Beans mit Anforderungsbereich außerhalb des DispatcherServlet zu verwenden, und habe dies gelesen http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html) /beans.html#beans-factory-scopes-other Hatten aber noch keinen Erfolg:

Bei Servlet 3.0+ kann dies programmgesteuert über die WebApplicationInitializer-Schnittstelle erfolgen.

(Ich verwende den neuesten Tomcat, also ist Servlet 3+)

Ich habe versucht, sowohl den RequestContextListener als auch den RequestContextFilter zu verwenden (in den Dokumenten heißt es, dass sie und das DispatcherServlet genau dasselbe tun), aber in beiden Fällen erhalte ich immer noch Fehler, weil mein automatisch verdrahtetes Objekt null ist:

Mein Versuch, den Filter zu registrieren

@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

    @Override public void onStartup( ServletContext servletContext ) throws ServletException {
        super.onStartup( servletContext )
        servletContext.addFilter("requestContextFilter", new RequestContextFilter() ).addMappingForUrlPatterns(null, false, "/*")
    }

Mein Versuch, den Listener zu registrieren

@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

    @Override public void onStartup( ServletContext servletContext ) throws ServletException {
        super.onStartup( servletContext )
        servletContext.addListener( new RequestContextListener() ) 
    }

Vermisse ich etwas Offensichtliches? Ich habe mir den Autokonfigurations-Quellcode für Spring Boot angesehen und bin noch auf nichts gestoßen.


[~ # ~] Update [~ # ~]

Ich war ein Idiot, ich hatte meinen Filter in meiner SpringSecurity-Konfiguration innerhalb der configure() -Methode hinzugefügt:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

hatte den neuen Filter aber nicht als Bean registriert. Laut dem Kommentar von M. Denium brauchte ich nicht die ganze zusätzliche Konfiguration, die explizit den Listener/Filter hinzufügte. Nur das Registrieren der Bean war genug.

33
rhinds

Wie in den Updates/Kommentaren beschrieben, wurde dies durch meine eigene Dummheit verursacht.

Spring-Boot ist in der Lage, Request/Session-Beans automatisch in Filter zu verdrahten, die sich außerhalb von DispatcherServlet befinden. Gemäß der Dokumentation von Spring müssen wir RequestContextListener oder RequestContextFilter hinzufügen, um dies zu aktivieren Diese Funktionalität:

Um das Scoping von Beans auf der Anforderungs-, Sitzungs- und globalen Sitzungsebene (Web-Scoped-Beans) zu unterstützen, sind einige geringfügige Erstkonfigurationen erforderlich, bevor Sie Ihre Beans definieren. (Diese anfängliche Einrichtung ist für die Standardbereiche Singleton und Prototyp nicht erforderlich.) ...

Wenn Sie innerhalb von Spring Web MVC auf Beans mit Gültigkeitsbereich zugreifen, die von Spring DispatcherServlet oder DispatcherPortlet verarbeitet werden, ist kein spezielles Setup erforderlich: DispatcherServlet und DispatcherPortlet machen bereits alle relevanten Status verfügbar.

Um dies zu handhaben, musste ich eine RequestContextListener-Bean registrieren:

@Bean public RequestContextListener requestContextListener(){
    return new RequestContextListener();
} 

Wenn Sie diese Bean nicht registrieren, erhalten Sie eine Fehlermeldung, dass Sie versuchen, auf den Request-Bereich außerhalb von DispatcherServlet zuzugreifen.

Das Problem (Autowired-Objekte wurden gerade nicht injiziert) wurde dadurch verursacht, dass ich meinen benutzerdefinierten Filter als Standardklasseninstanz und nicht als Spring-Managed-Bean registriert habe:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

Um dieses Problem zu lösen, habe ich die Erstellung von PreAuthFilter auf eine bestimmte @Bean - Methode verschoben. Die Funktion @Autowired Funktionierte dann einwandfrei.

50
rhinds