升级Spring Authorization Server 1.4.1后启动报错:找不到DelegatingAuthenticationConverter类
最近我把Spring OAuth2 Authorization Server从1.2版本升级到1.4.1版本后,启动项目直接炸了——执行./gradlw bootRun时构建失败,抛出了Bean创建异常。
错误日志
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authorizationServerSecurityFilterChain' defined in class path resource [com/something/auth_service/configuration/OAuth2SecurityConfig.class]: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'authorizationServerSecurityFilterChain' threw exception with message: org/springframework/security/web/authentication/DelegatingAuthenticationConverter
一开始我用spring-boot-starter-oauth2-authorization-server依赖时,它自动引入的是1.2.1版本的授权服务器,不是我想要的1.4.1,所以我就直接显式指定了依赖版本,结果就出问题了。
我的Build.Gradle配置
plugins { id 'java' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' id 'application' } group = 'com.something' version = '0.0.1-SNAPSHOT' application { mainClass = 'com.something.auth_service.AuthApplication' } java { sourceCompatibility = '17' } configurations { compileOnly { extendsFrom annotationProcessor } all { exclude group: 'commons-logging', module: 'commons-logging' } } repositories { mavenCentral() } bootRun { args = ["--spring.profiles.active=dev"] } bootTestRun { args = ["--spring.profiles.active=dev"] } dependencies { implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.0' implementation 'software.amazon.awssdk:ses:2.28.20' implementation 'software.amazon.awssdk:sdk-core:2.28.20' implementation 'software.amazon.awssdk:auth:2.28.20' implementation 'software.amazon.awssdk:s3:2.28.20' implementation 'software.amazon.awssdk:regions:2.28.20' implementation 'software.amazon.awssdk:utils:2.28.20' implementation 'software.amazon.awssdk:services:2.28.20' implementation 'software.amazon.awssdk:aws-core:2.28.20' implementation 'jakarta.mail:jakarta.mail-api:2.1.3' implementation 'software.amazon.awssdk:sesv2:2.28.20' implementation 'software.amazon.awssdk:auth:2.28.20' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-security:3.4.1' implementation 'org.springframework.boot:spring-boot-starter-web:3.4.1' implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'redis.clients:jedis:5.1.2' implementation 'com.sun.mail:javax.mail:1.6.0' implementation 'javax.mail:javax.mail-api:1.6.2' implementation 'org.hibernate.validator:hibernate-validator' implementation 'io.jsonwebtoken:jjwt-api:0.12.3' implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.4.1' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3' implementation 'javax.servlet:servlet-api:2.5' implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' } tasks.named('test') { useJUnitPlatform() }
我的OAuth2授权服务器配置
之前用旧版本时,登录路由和客户端注册都能正常工作,升级后就全崩了:
package com.something.auth_service.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.DelegatingPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.KeyPairGenerator; import com.something.auth_service.configuration.user.CustomUserDetailsService; import com.something.auth_service.configuration.user.UsernamePasswordAuthenticationProvider; import com.something.auth_service.repository.UserRepository; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import org.springframework.security.oauth2.jwt.JwtDecoder; import com.nimbusds.jose.proc.SecurityContext; import jakarta.servlet.http.HttpServletResponse; import java.security.KeyPair; @Order(Ordered.HIGHEST_PRECEDENCE) @Configuration public class OAuth2SecurityConfig { @Bean CustomUserDetailsService userDetailsService(UserRepository userRepository) { return new CustomUserDetailsService(userRepository); } @Bean public PasswordEncoder customPasswordEncoder() { String idForEncode = "bcrypt"; Map<String,PasswordEncoder> encoders = new HashMap<>(); encoders.put(idForEncode, new BCryptPasswordEncoder()); return new DelegatingPasswordEncoder("bcrypt", encoders); } @Bean public AuthenticationManager authenticationManager( CustomUserDetailsService userDetailsService, PasswordEncoder sharedPasswordEncoder) { UsernamePasswordAuthenticationProvider authenticationProvider = new UsernamePasswordAuthenticationProvider(userDetailsService, sharedPasswordEncoder); return new ProviderManager(authenticationProvider); } @Bean SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,RegisteredClientRepository registeredClientRepository, AuthorizationServerSettings authorizationServerSettings) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); // Failed below here. http .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) .with(authorizationServerConfigurer, (authorizationServer) -> authorizationServer .oidc((oidc) -> oidc.clientRegistrationEndpoint((clientRegistrationEndpoint) -> oidc.clientRegistrationEndpoint(Customizer.withDefaults()) ) ) ) .cors(cors -> cors.disable()) .csrf(csrf -> csrf.disable()) .authorizeHttpRequests((authorize) -> authorize .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers("/create-account").permitAll() .requestMatchers("/error").permitAll() .requestMatchers("/oauth2/authorize").permitAll() .requestMatchers("/login").permitAll() .anyRequest().authenticated() ) .formLogin(formLogin -> { formLogin.loginPage("/login"); formLogin.usernameParameter("emailOrUsername"); formLogin.passwordParameter("password"); formLogin.successHandler((request, response, authentication) -> { System.out.println("Login Succeeded."); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().write("Login successful!"); response.getWriter().flush(); }); }) .logout(logout -> { logout.logoutUrl("/logout"); }); return http.build(); } }
问题分析与解决建议
这个错误的核心原因是Spring Security版本和Authorization Server版本不兼容:
- Spring Authorization Server 1.4.1要求依赖Spring Security 6.3.x及以上版本
- 但你当前用的Spring Boot 3.2.0对应的Spring Security是6.2.x,手动指定的
spring-boot-starter-security:3.4.1其实和Spring Boot 3.2.0版本不匹配,导致依赖冲突
给你两个可行的解决方向:
- 升级Spring Boot版本:把Spring Boot版本升到3.3.x或更高,这样Spring的依赖管理会自动引入和Authorization Server 1.4.1兼容的Spring Security版本,不用手动指定starter-security的版本
- 手动对齐依赖版本:如果不想升级Spring Boot,就显式指定Spring Security的版本为6.3.x(比如6.3.0),确保和Authorization Server 1.4.1兼容
- 清理旧依赖:移除
javax.servlet:servlet-api:2.5这个过时依赖,Spring Boot 3.x用的是Jakarta Servlet API 6.0,旧依赖会干扰类加载
备注:内容来源于stack exchange,提问作者Grant mitchell
相关产品推荐
相关产品推荐

