Spring Security3.2.9升5.7.1时BasicAuthenticationFilter实例化报错
问题描述
- 升级场景:将Spring Security从3.2.9版本升级至5.7.1版本,同时将Spring框架从3.2.13版本升级至5.3.20版本
- 启动报错:实例化
BasicAuthenticationFilter时提示找不到默认构造函数,核心错误信息:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.authentication.www.BasicAuthenticationFilter]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.security.web.authentication.www.BasicAuthenticationFilter.<init>()
- 原有错误配置(全属性注入方式):
<beans:bean id="basicAuth" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter" > <beans:property name="authenticationManager" ref="authenticationManager"/> <beans:property name="authenticationEntryPoint" ref="basicAuthEntryPoint" /> </beans:bean>
- 尝试过的无效调整(仅补充第二个构造参数,同时保留属性注入):
<beans:bean id="basicAuth" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter" > <beans:property name="authenticationManager" ref="authenticationManager"/> <beans:property name="authenticationEntryPoint" ref="basicAuthEntryPoint" /> <beans:constructor-arg index="1" ref="basicAuthEntryPoint" /> </beans:bean>
报错根因
从Spring Security 4.x版本开始,BasicAuthenticationFilter就已经完全移除了无参构造函数和对应的属性setter方法,仅保留两个带参构造方法:
- 单参构造:仅传入
AuthenticationManager实例,使用默认的Basic认证入口点 - 双参构造:依次传入
AuthenticationManager实例、自定义AuthenticationEntryPoint实例
之前的两种配置都无法匹配到现有构造函数:
- 第一种全属性注入的配置,会默认调用无参构造实例化Bean,再通过set方法注入属性,但无参构造已经不存在,直接抛出异常
- 第二种调整后的配置,只传入了索引为1的第二个构造参数,缺失了索引为0的必填
AuthenticationManager参数,同时还保留了已经不存在的setter属性注入配置,依然无法完成实例化。
修复方案
删除所有<property>属性注入配置,全部改用构造器按参数顺序传入依赖,正确配置如下:
<beans:bean id="basicAuth" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> <!-- 第1个必填构造参数:认证管理器 --> <beans:constructor-arg index="0" ref="authenticationManager"/> <!-- 第2个可选构造参数:自定义认证入口点,不需要自定义可删除该行 --> <beans:constructor-arg index="1" ref="basicAuthEntryPoint"/> </beans:bean>
注意:跨大版本升级Spring Security时,所有自定义的安全过滤器、配置类都需要核对API签名变更,高版本中大量原先支持setter注入的组件都移除了无参构造,统一改为构造器注入来保证依赖不可变性,旧版本的属性注入写法会直接失效。
内容的提问来源于stack exchange,提问作者Pavan Kumar Tiruvaipati
相关产品推荐
相关产品推荐

