spring - 我可以将 Spring MVC servlet 的 WebApplicationContext 注入(inject) DelegatingFilterProxy 吗?

标签 spring spring-mvc spring-security

我正在创建一个 OAuth 授权服务器,它使用 Spring Security 作为我的 servlet 部分的安全层。其中一个重要部分是使用 DelegatingFilterProxy 映射到 springSecurityFilterChain bean,它需要一个 WebApplicationContext 实例。

标准解决方案是包含一个 ContextLoaderListener 以及关联的 contextConfigLocation 配置。但这需要为根 WebApplicationContext 创建单独的配置,在我看来,这不必要地使问题复杂化。

根据 Spring MVC 文档,每个 DispatcherServlet 都有它自己的 WebApplicationContext 实例。更重要的是,通过仔细阅读 DelegatingFilterProxy 的代码,应该可以在构造时注入(inject) WebApplicationContext 实例。

所以我的问题是:我可以将 DispatcherServlet WebApplicationContext 设置为 DelegatingFilterProxy 的实例吗?

这是我目前的相关配置:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="
            http://xmlns.jcp.org/xml/ns/javaee
            http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <!-- Enable Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>oauth</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>    
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/servlet.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>oauth</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/security/oauth2
        http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">

    <mvc:annotation-driven/>

    <!-- ... Spring MVC config ... -->

    <!-- Spring Security OAuth Config -->
    <security:global-method-security pre-post-annotations="enabled" />

    <oauth:authorization-server client-details-service-ref="clientDetails"
                                token-services-ref="tokenServices"
                                token-endpoint-url="/api/token">
        <oauth:refresh-token/>
        <oauth:client-credentials/>
    </oauth:authorization-server>

    <!-- ... loads more OAuth config ... -->

</beans>

最佳答案

DispatcherServlet (作为 FrameworkServlet 的任何子类)将发布其 WebApplicationContextServletContext使用属性名称:org.springframework.web.servlet.FrameworkServlet.CONTEXT.<servlet-name> .

同时DelegatingFilterProxy可以告诉不要使用root WebApplicationContext但另一个存储在 ServletContext 中通过设置其 contextAttribute参数。

在您的情况下,所需的配置是:

<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.oauth </param-value>
    </init-param>
</filter>

查看有关如何操作的更多信息 DelegatingFilterProxy查找 WebApplicationContext findWebApplicationContext() 的javadoc中.

关于spring - 我可以将 Spring MVC servlet 的 WebApplicationContext 注入(inject) DelegatingFilterProxy 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17922459/

相关文章:

java - activemq 代理启动后是否可以创建虚拟目的地和复合队列?

java - 如何跨不同 JVM 保留对象标识

java - 为自定义 userdetailsservice 定义 bean

caching - 注入(inject)和使用 Spring Security UserCache

java - (Jackson) 如何使用另一个对象的属性将 JSON 反序列化为具有多态性的 POJO?

java - HQL 检查字段是否包含字符串列表中的任何字符串

java - 使用 Maven 的 SpringMVC 和 Hibernate

java - Spring MVC 3 - @ResponseBody 方法如何呈现 JSTLView?

java - Spring XML 配置不起作用 -

spring-security - Spring Cloud Gateway POST 禁止