Настройка 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 ниже, мне не понадобилась вся эта дополнительная конфигурация, явно добавляющая слушатель/фильтр, достаточно было зарегистрировать компонент.
Ответы
Ответ 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
работала нормально.