Spring 从 4.3 升级到 5.3 会导致 Spring Security 和 Spring MVC 缺少 bean 错误

Spring upgrade from 4.3 to 5.3 causes missing bean error with Spring Security and Spring MVC

提问人:quantumferret 提问时间:11/24/2022 更新时间:11/24/2022 访问量:431

问:

我正在将一个相当大的项目从 Spring 4.3.30.RELEASE 升级到 Spring 5.3.23,并将 Spring Security 依赖项从前者升级到 Spring Security 5.7.5。它完全通过 XML 配置文件进行配置。似乎与该问题相关的是 、 和 。这是部署在本地 JBoss/Wildfly 服务器上时发生的错误(当我尝试使用带有嵌入式 Tomcat 9 的 Spring Boot 应用程序部署 WAR 时,我遇到了同样的错误,所以这似乎不是特定于 JBoss/Wildfly 的):/webapp/WEB-INF/local-web.xml/webapp/WEB-INF/mvc-configuration.xml/resources/spring/local-security-config.xml

15:36:58,552 INFO  [stdout] (ServerService Thread Pool -- 209) ERROR [ServerService Thread Pool -- 209] o.s.web.context.ContextLoader - Context initialization failed
15:36:58,552 INFO  [stdout] (ServerService Thread Pool -- 209) org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0];
    nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot create inner bean '(inner bean)#29f4d2ab' of type [org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher] while setting constructor argument;
    nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#29f4d2ab': Cannot create inner bean '(inner bean)#354eace3' of type [org.springframework.security.config.http.HandlerMappingIntrospectorFactoryBean] while setting constructor argument;
    nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#354eace3': FactoryBean threw exception on object creation;
    nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mvcHandlerMappingIntrospector' available: A Bean named mvcHandlerMappingIntrospector of type org.springframework.web.servlet.handler.HandlerMappingIntrospector is required to use MvcRequestMatcher. 
    Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.
15:36:58,552 INFO  [stdout] (ServerService Thread Pool -- 209)  at ....

我觉得我错过了一些非常明显的东西,因为我已经翻阅了 Baeldung 关于这个错误的帖子,以及 5 个(给予或接受)StackOverflow 问题,这些问题也涉及这个问题或我发现的密切相关的问题,但没有任何效果。以下是(可能的)相关文件:

本地 web.xml:

<!-- local-web.xml -->

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
       id="WebApp_ID" version="4.0">

   <display-name>SpringWebApp</display-name>

   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
         classpath:spring/root.xml
         classpath:spring/local-security.xml
      </param-value>
   </context-param>

   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <servlet>
      <servlet-name>dispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/mvc-configuration.xml</param-value>
      </init-param>
      <init-param>
         <param-name>development</param-name>
         <param-value>true</param-value>
      </init-param>
      <load-on-startup>2</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>dispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
   </servlet-mapping>
   
   <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>

   <filter>
      <filter-name>entityManagerInViewFilter</filter-name>
      <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
   </filter>

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

</web-app>

mvc-configuration.xml:

<!-- mvc-configuration.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:sec="http://www.springframework.org/schema/security"
   xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
      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/security http://www.springframework.org/schema/security/spring-security.xsd"
      >

   <context:component-scan base-package="com.my.base.package"/>


    <mvc:annotation-driven />

   <sec:global-method-security pre-post-annotations="enabled" secured-annotations="enabled" >
       <sec:expression-handler ref="methodSecurityExpressionHandler"/> <!-- methodSecurityExpressionHandler is defined in local-security-config.xml -->
   </sec:global-method-security>

   <!-- ***** -->
   <!-- Thymeleaf-specific -->
   <!-- ***** -->
   <bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
      <property name="prefix" value="/WEB-INF/templates/" />
      <property name="suffix" value=".html" />
      <property name="templateMode" value="HTML5" />
      <property name="characterEncoding" value="UTF-8" />
      <property name="cacheable" value="false" />
   </bean>
   <bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
      <property name="templateResolver" ref="templateResolver" />
      <property name="additionalDialects">
         <set>
            <bean class="org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect"/>
         </set>
      </property>
   </bean>
   <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
      <property name="templateEngine" ref="templateEngine" />
      <property name="contentType" value="text/html;charset=UTF-8"></property>
      <property name="characterEncoding" value="UTF-8" />
   </bean>

   <bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      <property name="maxUploadSize" value="100000000" />
   </bean>
      
</beans>

本地安全配置.xml:

<!-- local-security-config.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:sec="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/security http://www.springframework.org/schema/security/spring-security.xsd">

   <sec:http pattern="/api/**" use-expressions="true" authentication-manager-ref="authenticationManager" request-matcher="mvc">
      <sec:intercept-url pattern="/**" access="hasRole('CALL_WS_ANY') or hasAuthority('CALL_WS_ANY')"/>
      <sec:http-basic />
      <sec:csrf disabled="true"/>
   </sec:http>

   <sec:http pattern="/test/*" use-expressions="true"
           authentication-manager-ref="authenticationManager">
      <sec:expression-handler ref="webSecurityExpressionHandler"/>
      <sec:intercept-url pattern="/test/**" access="hasRole('VIEW?')"/>
      <sec:http-basic/>
      <sec:csrf disabled="true"/>
   </sec:http>

   <sec:http pattern="/posts*" use-expressions="true"
           authentication-manager-ref="authenticationManager">
      <sec:expression-handler ref="webSecurityExpressionHandler"/>
      <sec:intercept-url pattern="/posts**" access="hasRole('VIEW?')"/>
      <sec:http-basic/>
      <sec:csrf disabled="true"/>
   </sec:http>

   <sec:http use-expressions="true" authentication-manager-ref="authenticationManager">
      <sec:expression-handler ref="webSecurityExpressionHandler"/>

      <sec:intercept-url pattern="/login" access="permitAll"/>
      <sec:intercept-url pattern="/leave" access="permitAll"/>

      <sec:form-login/>
      <sec:csrf disabled="false"/>

      <sec:access-denied-handler error-page="/leave?code=deny"/>
      <sec:logout invalidate-session="true" logout-url="/logout" logout-success-url="/leave?code=success" delete-cookies="JSESSIONID"/>
   </sec:http>

   <sec:authentication-manager alias="authenticationManager">
      <sec:authentication-provider>
         <sec:user-service>
            <sec:user name="view" password="view" authorities="ROLE_VIEW?" />
            <sec:user name="edit" password="edit" authorities="ROLE_VIEW?, ROLE_EDIT?" />
         </sec:user-service>
      </sec:authentication-provider>
      <sec:authentication-provider>
         <sec:user-service id="inMemoryUserDetailsService">
            <sec:user name="${username}" password="${password}" authorities="CALL_WS_ANY"/>
         </sec:user-service>
      </sec:authentication-provider>
   </sec:authentication-manager>

   <bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
   <!--  referenced in mvc-configuration.xml -->
   <bean id="methodSecurityExpressionHandler"
        class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"/>
</beans>

我认为相关依赖项已正确更新,依赖项树中没有 Spring/Spring Security 4 工件,我只更新了 servlet 版本和 URL 以及 Thymeleaf beans 的类路径;否则,文件将保持不变。local-web.xmlmvc-configuration.xml

任何帮助将不胜感激。

java spring-mvc spring-security xml-configuration

评论


答: 暂无答案