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

Spring Boot集成Azure AD OAuth2报错缺失client_id参数如何解决

问题根因

该错误触发在OAuth2授权码流程的授权码兑换access_token阶段:前期获取授权code时携带了client_id不代表后续兑换token的请求会自动携带该参数,你遇到的情况就是Spring底层发送兑换token的请求时,未将client_id写入请求体导致的。

解决方案

1. 修正配置项

3.x版本的Azure AD Starter有专属的配置规则,很多用户会混用旧版本配置键导致参数丢失,完整必填配置如下:

# 基础配置
azure.activedirectory.client-id=替换为你的实际client_id
azure.activedirectory.client-secret=替换为你的实际客户端密钥
azure.activedirectory.tenant-id=替换为你的实际租户ID
# 授权客户端配置(3.x版本必填,遗漏会导致兑换token时缺参数)
azure.activedirectory.authorization-clients.azure.client-id=替换为你的实际client_id
azure.activedirectory.authorization-clients.azure.client-secret=替换为你的实际客户端密钥

2. 移除冗余依赖

com.azure.spring:azure-spring-boot-starter-active-directory:3.9.0已经内置了Spring OAuth2客户端的相关依赖,你手动引入的org.springframework.boot:spring-boot-starter-oauth2-client:2.4.2可能和Azure Starter依赖的版本不兼容,导致请求参数序列化异常。请删除build.gradle.kts中手动引入oauth2-client的那行依赖,重新构建项目后测试。

3. 强制注入client_id参数(前两个方案无效时使用)

如果以上方案都未解决问题,可以自定义授权码兑换token的请求逻辑,强制将client_id写入请求体,示例代码如下:

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest
import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationCodeGrantRequestEntityConverter

@Configuration
class AzureOAuth2Config {

    @Bean
    fun authorizationCodeTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> {
        val tokenResponseClient = DefaultAuthorizationCodeTokenResponseClient()
        val requestEntityConverter = OAuth2AuthorizationCodeGrantRequestEntityConverter()
        
        // 自定义参数转换器,强制添加client_id到请求体
        requestEntityConverter.addParametersConverter { grantRequest ->
            val clientRegistration = grantRequest.clientRegistration
            mutableMapOf(
                "client_id" to listOf(clientRegistration.clientId),
                "client_secret" to listOf(clientRegistration.clientSecret)
            )
        }
        
        tokenResponseClient.setRequestEntityConverter(requestEntityConverter)
        tokenResponseClient.setErrorHandler(OAuth2ErrorResponseErrorHandler())
        return tokenResponseClient
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:45:03