我有一个使用Spring-Security的Spring-Boot应用程序。我有一个请求范围的bean,我想自动装入安全过滤器链中的一个自定义过滤器,但目前它不工作。
我知道在DispatcherServlet之外使用请求范围的bean需要一些配置,并且已经读过这个http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other但是还没有取得任何成功:
对于Servlet 3.0+,可以通过以编程方式完成 WebApplicationInitializer接口。
(我正在使用最新的Tomcat,因此是servlet 3 +)
我尝试过同时使用RequestContextListener和RequestContextFilter(文档说它们和DispatcherServlet完全相同),但在这两种情况下我仍然会收到错误,因为我的自动对象是空的:
我尝试注册过滤器
@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 )
但尚未将新过滤器注册为Bean。根据M. Denium在下面的评论,我并不需要所有额外的配置显式添加监听器/过滤器,只需注册bean就足够了。
答案 0 :(得分:46)
如更新/评论中所详述,这是由我自己的愚蠢造成的。
Spring-Boot能够将请求/会话范围的bean自动装配到DispatcherServlet
之外的过滤器中。根据Spring的文档,我们需要添加RequestContextListener
或RequestContextFilter
来启用此功能:
支持请求,会话和全局bean的范围 会话级别(web-scoped beans),一些次要的初始配置是 在定义bean之前需要。 (这个初始设置不是 标准示波器,单件和原型所需。) ...
如果你在Spring Web MVC中访问scoped bean,实际上是在一个 由Spring DispatcherServlet处理的请求,或 DispatcherPortlet,则无需特殊设置: DispatcherServlet和DispatcherPortlet已公开所有相关内容 状态。
为了解决这个问题,我需要注册一个RequestContextListener bean:
@Bean public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
如果您没有注册该bean,您将收到一条错误消息,指出您正在尝试访问DispatcherServlet之外的Request范围。
我遇到的问题(自动对象没有被注入)是由于我只是将自定义过滤器注册为标准类实例,而不是Spring托管bean:
http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )
要解决这个问题,我只是将PreAuthFilter
的创建移到了一个sepearte @Bean
方法,然后@Autowired
功能正常运行。