You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Spring Authorization Server 1.4.1后启动报错:找不到DelegatingAuthenticationConverter类

升级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版本不匹配,导致依赖冲突

给你两个可行的解决方向:

  1. 升级Spring Boot版本:把Spring Boot版本升到3.3.x或更高,这样Spring的依赖管理会自动引入和Authorization Server 1.4.1兼容的Spring Security版本,不用手动指定starter-security的版本
  2. 手动对齐依赖版本:如果不想升级Spring Boot,就显式指定Spring Security的版本为6.3.x(比如6.3.0),确保和Authorization Server 1.4.1兼容
  3. 清理旧依赖:移除javax.servlet:servlet-api:2.5这个过时依赖,Spring Boot 3.x用的是Jakarta Servlet API 6.0,旧依赖会干扰类加载

备注:内容来源于stack exchange,提问作者Grant mitchell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:23:10