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

仅配置客户端凭证时ReactiveOAuth2AuthorizedClientManager未自动配置

ReactiveOAuth2AuthorizedClientManager未自动配置的原因排查

我创建了一个基于WebFlux的极简响应式应用,引入OAuth2客户端starter并配置了provider和registration属性,但ReactiveOAuth2AuthorizedClientManager未被自动配置。

POM文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.c4-soft.springaddons.sample</groupId>
    <artifactId>http-exchange-reactive</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <description>Resource server with custom authentication manager</description>
    <properties>
        <java.version>21</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

应用配置

keycloak-base-uri: https://localhost:8443/auth
issuer: ${keycloak-base-uri}/realms/master
keycloak-admin-api-consumer-secret: change-me

spring:
  security:
    oauth2:
      client:
        provider:
          keycloak:
           issuer-uri: ${issuer}
        registration:
          backend-with-client-credentials:
            provider: keycloak
            authorization-grant-type: client_credentials
            client-id: keycloak-admin-api-consumer
            client-secret: ${keycloak-admin-api-consumer-secret}
            scope: openid

复现代码

@SpringBootApplication
public class HttpClientReactiveApplication {

    public static void main(String[] args) {
        SpringApplication.run(HttpClientReactiveApplication.class, args);
    }

    @Bean
    Converter<String, String> failToInject(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
        return source -> source;
    }

}

启动错误日志

2024-02-19T15:01:51.575-10:00[0;39m [32m INFO[0;39m [35m21168[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mc.c.o.HttpClientReactiveApplication     [0;39m [2m:[0;39m Starting HttpClientReactiveApplication using Java 21 with PID 21168 (D:\workspaces\libs\http-client-reactive\target\classes started by ch4mp in D:\workspaces\libs\http-client-reactive)
[2m2024-02-19T15:01:51.577-10:00[0;39m [32m INFO[0;39m [35m21168[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mc.c.o.HttpClientReactiveApplication     [0;39m [2m:[0;39m No active profile set, falling back to 1 default profile: "default"
[2m2024-02-19T15:01:52.949-10:00[0;39m [33m WARN[0;39m [35m21168[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36monfigReactiveWebServerApplicationContext[0;39m [2m:[0;39m Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'failToInject' defined in com.c4soft.openfeign.HttpClientReactiveApplication: Unsatisfied dependency expressed through method 'failToInject' parameter 0: No qualifying bean of type 'org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
[2m2024-02-19T15:01:52.966-10:00[0;39m [32m INFO[0;39m [35m21168[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36m.s.b.a.l.ConditionEvaluationReportLogger[0;39m [2m:[0;39m 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
[2m2024-02-19T15:01:52.995-10:00[0;39m [31mERROR[0;39m [35m21168[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mo.s.b.d.LoggingFailureAnalysisReporter  [0;39m [2m:[0;39m 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method failToInject in com.c4soft.openfeign.HttpClientReactiveApplication required a bean of type 'org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager' in your configuration.

问题原因及解决方案

核心原因

你同时引入了spring-boot-starter-oauth2-resource-server和spring-boot-starter-oauth2-client依赖,Spring Security的自动配置逻辑中,资源服务器模式的优先级高于OAuth2客户端模式。当应用同时包含这两种角色时,自动配置会优先启用资源服务器相关组件,而OAuth2客户端侧的ReactiveOAuth2AuthorizedClientManager等Bean不会被自动初始化。

另外,ReactiveOAuth2AuthorizedClientManager的自动配置类生效条件之一是:上下文未被资源服务器的配置逻辑覆盖,而你的场景中资源服务器配置抢占了初始化优先级。

解决方案

方案1:手动配置ReactiveOAuth2AuthorizedClientManager

直接在配置类中声明该Bean,适配客户端凭证模式:

@Bean
public ReactiveOAuth2AuthorizedClientManager reactiveOAuth2AuthorizedClientManager(
        ReactiveClientRegistrationRepository clientRegistrationRepository,
        ServerOAuth2AuthorizedClientService authorizedClientService) {

    ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
            ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
                    .clientCredentials()
                    .build();

    AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
            new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
                    clientRegistrationRepository, authorizedClientService);
    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

    return authorizedClientManager;
}

方案2:同时启用资源服务器和客户端配置

自定义SecurityFilterChain,明确同时配置两种模式的规则,触发Spring Security初始化双方的组件:

@Bean
public SecurityFilterChain securityFilterChain(ServerHttpSecurity http) throws Exception {
    http
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .oauth2Client(Customizer.withDefaults());
    return http.build();
}

内容的提问来源于stack exchange,提问作者ch4mp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:52:35