spring - 在 SpringBoot 中配置 RequestContextListener

标签 spring spring-mvc spring-security spring-boot

我有一个使用 Spring-Security 的 Spring-Boot 应用程序。我有一个请求范围的 bean,我想将它 Autowiring 到安全过滤器链中的一个自定义过滤器中,但目前它不起作用。

我了解在 DispatcherServlet 之外使用请求范围的 bean 需要一些配置,并且已阅读此 http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other但是还没有成功:

For Servlet 3.0+, this can done programmatically via the WebApplicationInitializer interface.

(我使用的是最新的 Tomcat,servlet 3+ 也是)

我尝试过同时使用 RequestContextListener 和 RequestContextFilter(文档说它们和 DispatcherServlet 做的事情完全相同),但在这两种情况下我仍然会遇到错误,因为我的 Autowiring 对象为空:

我尝试注册过滤器

@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 就足够了。

最佳答案

如更新/评论中所述,这是我自己的愚蠢造成的。

Spring-Boot 能够将 Request/Session 范围的 bean Autowiring 到 DispatcherServlet 之外的过滤器中。根据 Spring 的文档,我们需要添加 RequestContextListenerRequestContextFilter 来启用这个功能:

To support the scoping of beans at the request, session, and global session levels (web-scoped beans), some minor initial configuration is required before you define your beans. (This initial setup is not required for the standard scopes, singleton and prototype.) ...

If you access scoped beans within Spring Web MVC, in effect, within a request that is processed by the Spring DispatcherServlet, or DispatcherPortlet, then no special setup is necessary: DispatcherServlet and DispatcherPortlet already expose all relevant state.

为了处理这个问题,我需要注册一个 RequestContextListener bean:

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

如果您不注册该 bean,您将收到一条错误消息,指出您正在尝试访问 DispatcherServlet 之外的 Request 范围。

我遇到的问题(只是没有注入(inject) Autowiring 的对象)是因为我只是将自定义过滤器注册为标准类实例,而不是 Spring 托管 bean:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

为了解决这个问题,我只是将 PreAuthFilter 的创建移到了一个单独的 @Bean 方法中,然后 @Autowired 功能就可以正常工作了.

关于spring - 在 SpringBoot 中配置 RequestContextListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30254079/

相关文章:

java - 我想使用 spring3.0 和 java 创建一个 web 应用程序

Spring Security OAuth - 它可以使用来自 Keycloak 的 JWT token 吗

java - 如何动态生成bean列表

java - 使用 Java Spring JPA 和 CRUD 更新数据库记录

java - 如何在 Spring MVC 4 中的 Servlet 中注入(inject)依赖?

angular - 部署在本地 tomcat 服务器上的 Angular 应用程序的 url 不会在将 url 粘贴到浏览器的新选项卡上时加载组件

html - JSP 中的 Spring MVC 请求 URL

java - 当另一个任务完成执行时,在一定时间后安排任务

java - 找不到具有 starter-security 依赖项的 springframework.security 包?

java - Spring Security for Active Directory 搜索为 'userPrincipalName'——有办法改变这个吗?