启动Jetty时遇Spring Security错误:找不到指定DelegatingFilterProxy Bean
我明白你已经试过现有方案但都没解决这个问题,咱们来针对性排查这个Jetty+Spring Security的Bean找不到错误。这个错误的核心是Spring容器找不到DelegatingFilterProxy对应的Bean,而名字带的随机后缀(比如-1b68ddbd),大概率是Jetty自动给Filter生成了唯一标识,导致DelegatingFilterProxy用这个带后缀的名字去查找Bean,自然找不到目标Bean。下面是几个针对性的排查和解决方向:
1. 明确指定DelegatingFilterProxy的目标Bean名称
不管你是通过web.xml还是Jetty API注册Filter,一定要显式指定targetBeanName为springSecurityFilterChain——这是Spring Security自动创建的核心Filter Bean,只要你正确配置了Spring Security就应该存在。
如果用web.xml注册:
确保filter-name就是springSecurityFilterChain,或者通过init-param指定目标Bean:<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- 显式指定目标Bean,避免Jetty自动命名干扰 --> <init-param> <param-name>targetBeanName</param-name> <param-value>springSecurityFilterChain</param-value> </init-param> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>如果用Jetty API动态注册:
不要依赖默认的Filter命名,直接设置targetBeanName参数:ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); // 创建DelegatingFilterProxy的FilterHolder FilterHolder securityFilterHolder = new FilterHolder(DelegatingFilterProxy.class); // 关键:显式指定要查找的Bean名称 securityFilterHolder.setInitParameter("targetBeanName", "springSecurityFilterChain"); // 添加Filter到Jetty上下文 context.addFilter(securityFilterHolder, "/*", EnumSet.allOf(DispatcherType.class));
2. 确认Spring Security配置已正确加载
检查你的applicationContext.xml或单独的Spring Security配置文件:
- 确保已经引入Spring Security的命名空间,比如:
<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>核心节点,这是Spring Security自动生成springSecurityFilterChain的前提:<sec:http auto-config="true"> <!-- 你的权限规则配置 --> <sec:intercept-url pattern="/**" access="authenticated"/> <sec:form-login/> </sec:http> - 如果Spring Security配置在单独的文件里,要确保被主上下文正确引入:
<import resource="classpath:spring-security.xml"/>
3. 排查Spring上下文的加载范围和顺序
- 确保
springSecurityFilterChain存在于DelegatingFilterProxy能访问到的Spring上下文里。一般来说,Spring Security的Bean应该放在根上下文(applicationContext.xml),而DelegatingFilterProxy默认会从根上下文查找Bean,不要把Security配置放到Servlet的子上下文里。 - 检查启动日志,看看是否有多个Spring ApplicationContext被初始化,避免Filter所在的上下文和Security Bean所在的上下文不一致。
4. 验证依赖版本兼容性
Spring Security、Spring Core和Jetty的版本不兼容也可能导致这类奇怪的Bean查找问题:
- 比如Spring Security 5.x需要搭配Spring 5.x及以上版本;Jetty 9.4.x对Spring 5.x的支持更稳定,Jetty 10+则需要Spring 5.3+。
- 可以尝试调整版本到官方推荐的兼容组合,比如:
- Spring Core 5.3.x + Spring Security 5.7.x + Jetty 9.4.x
5. 启用调试日志定位问题
开启Spring的DEBUG级别日志,重点查看Bean初始化和Filter查找过程:
- 在日志配置文件(比如logback.xml)中添加:
<logger name="org.springframework.beans.factory" level="DEBUG"/> <logger name="org.springframework.web.filter.DelegatingFilterProxy" level="DEBUG"/> - 从日志里你可以看到:
springSecurityFilterChain是否被Spring容器正确初始化;- DelegatingFilterProxy实际尝试查找的Bean名称是什么;
- 容器中所有已注册的Bean列表,对比就能找到问题根源。
内容的提问来源于stack exchange,提问作者Chry007

