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

Spring Security 5下同OAuth2授权服务器的两资源服务客户端模式调用方案咨询

Spring Security 5+ 客户端凭证模式跨资源服务调用实现方案

1. 引入核心依赖

需在发起调用的服务中引入OAuth2客户端启动器,Maven依赖示例如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. 配置OAuth2客户端参数

在application.yml中添加授权服务器、客户端凭证相关配置:

spring:
  security:
    oauth2:
      client:
        registration:
          # 自定义客户端注册ID,后续配置会用到
          target-service-client:
            client-id: 你的客户端ID
            client-secret: 你的客户端密钥
            authorization-grant-type: client_credentials
            # 填目标资源服务要求的scope
            scope: target-service:read,target-service:write
        provider:
          target-service-client:
            # 授权服务器的令牌颁发接口地址
            token-uri: http://你的授权服务器地址/oauth2/token

3. 配置带自动令牌注入的RestTemplate

Spring Security 5已原生提供客户端凭证模式的令牌自动管理能力,无需手动调用/oauth2/token接口获取令牌,直接配置拦截器即可:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.http.OAuth2ClientHttpRequestInterceptor;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;

@Configuration
public class OAuth2RestConfig {

    @Bean
    public OAuth2AuthorizedClientManager clientCredentialsAuthorizedClientManager(
            ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientRepository authorizedClientRepository) {
        // 仅启用客户端凭证模式的令牌提供者
        OAuth2AuthorizedClientProvider provider = OAuth2AuthorizedClientProviderBuilder
                .builder()
                .clientCredentials()
                .build();

        DefaultOAuth2AuthorizedClientManager manager = new DefaultOAuth2AuthorizedClientManager(
                clientRegistrationRepository,
                authorizedClientRepository
        );
        manager.setAuthorizedClientProvider(provider);
        return manager;
    }

    @Bean
    public RestTemplate oauth2ClientRestTemplate(OAuth2AuthorizedClientManager manager) {
        RestTemplate restTemplate = new RestTemplate();
        // 添加OAuth2请求拦截器,自动处理令牌获取、缓存、刷新、请求头注入
        OAuth2ClientHttpRequestInterceptor interceptor = new OAuth2ClientHttpRequestInterceptor(manager);
        restTemplate.setInterceptors(Collections.singletonList(interceptor));
        return restTemplate;
    }
}

4. 调用目标服务受保护接口

直接注入上述配置的oauth2ClientRestTemplate发起调用即可,框架会自动处理令牌相关逻辑:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class TargetServiceCaller {

    @Autowired
    @Qualifier("oauth2ClientRestTemplate")
    private RestTemplate oauth2RestTemplate;

    public String getProtectedResource() {
        // 目标资源服务的受保护接口地址
        String endpoint = "http://目标资源服务地址/protected/api";
        return oauth2RestTemplate.getForObject(endpoint, String.class);
    }
}

常见失败原因排查

  • 客户端注册时未开通client_credentials授权模式,导致令牌请求被授权服务器拒绝
  • 配置的scope未包含目标资源服务要求的权限范围,拿到的令牌访问资源时返回403
  • 手动调用令牌接口时Authorization请求头格式错误,正确格式为Bearer 令牌值(Bearer和令牌中间需加空格)
  • 授权服务器要求令牌的aud(受众)字段包含目标资源服务标识,需在客户端注册时配置对应受众参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:15:08