Подтвердить что ты не робот

Настройка RequestContextListener в SpringBoot

У меня есть приложение Spring-Boot, которое использует Spring-Security. У меня есть обработанная область запроса, которую я хочу передать в один из моих настраиваемых фильтров в цепочке фильтров безопасности, но на данный момент она не работает.

Я понимаю, что некоторые конфигурации необходимы для использования бранд-зонда, зависящего от объекта, за пределами DispatcherServlet, и прочитали это http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html # beans-factory-scopes-other Но пока не удалось добиться успеха:

Для сервлета 3. 0+ это можно сделать программно через интерфейс WebApplicationInitializer.

(Я использую последний Tomcat, так что это сервлет 3+)

Я пробовал использовать как RequestContextListener, так и RequestContextFilter (docs говорят, что они и DispatcherServlet делают то же самое), но в обоих случаях я все еще получаю ошибки, потому что мой объект с автосоединением имеет значение null:

Моя попытка зарегистрировать фильтр

@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, "/*")
    }

Моя попытка зарегистрировать слушателя

@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() ) 
    }

Мне что-то не хватает? Я просмотрел исходный код автоматической конфигурации для Spring Boot и ничего не нашел.


ОБНОВИТЬ

Я был идиотом, я добавил свой фильтр в моей конфигурации SpringSecurity внутри метода configure():

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

но не зарегистрировал новый фильтр в качестве компонента. Как и в случае с сообщением M. Denium ниже, мне не понадобилась вся эта дополнительная конфигурация, явно добавляющая слушатель/фильтр, достаточно было зарегистрировать компонент.

4b9b3361

Ответ 1

Как указано в обновлении/комментариях, это было вызвано моей собственной глупостью.

Spring-Boot может авторизовать bean-объекты Request/Session в фильтр, которые находятся за пределами DispatcherServlet Согласно документации Spring, нам нужно добавить RequestContextListener или RequestContextFilter чтобы включить эту функцию:

Чтобы поддерживать область видимости компонентов на уровнях запросов, сеансов и глобальных сеансов (компоненты с веб-областью), перед определением ваших компонентов необходимо выполнить небольшую первоначальную настройку. (Эта начальная настройка не требуется для стандартных областей, одиночных и прототипов.)...

Если вы получаете доступ к облачным компонентам в Spring Web MVC, в действительности, в запросе, который обрабатывается Spring DispatcherServlet или DispatcherPortlet, тогда никакой специальной настройки не требуется: DispatcherServlet и DispatcherPortlet уже отображают все соответствующие состояния.

Чтобы справиться с этим, мне нужно было зарегистрировать компонент RequestContextListener:

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

Если вы не зарегистрируете этот компонент, вы получите сообщение об ошибке, указывающее, что вы пытаетесь получить доступ к области запроса вне DispatcherServlet.

Проблема, с которой я столкнулся (объекты, которые не были введены в систему, были вызваны тем фактом, что я просто регистрировал свой настраиваемый фильтр как экземпляр стандартного класса, а не управляемый Spring компонент:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

Чтобы решить эту проблему, я просто переместил создание PreAuthFilter в метод sepearte @Bean, @Autowired функция @Autowired работала нормально.