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

Azure AD OpenID Connect刷新AccessToken失败,求正确请求方式

Azure AD OIDC认证刷新令牌请求错误修正

你的代码存在几个关键问题,导致刷新令牌请求失败:

核心错误点

  1. 使用了错误的Token端点:你当前用的是OIDC发现文档地址(https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration),但实际刷新令牌需要调用该文档里返回的token_endpoint字段对应的URL,而非发现文档本身。
  2. 多余的Bearer授权头:刷新令牌请求不需要携带原access token的Bearer授权,Azure AD的token端点仅需通过表单参数验证客户端身份(client_id+client_secret)和刷新令牌。
  3. 可能缺失的Scope参数:若需要获取特定权限的新access token,需在请求中添加scope参数,值为初始认证时使用的权限列表(比如openid profile email),否则会返回默认权限的令牌。

正确的请求实现步骤

1. 获取正确的Token端点

从OIDC发现文档中解析出实际的token端点:

var discoveryClient = new HttpClient();
var discoveryDoc = await discoveryClient.GetFromJsonAsync<dynamic>("https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration");
var tokenEndpoint = discoveryDoc.token_endpoint;

2. 构造正确的请求参数

移除多余的Bearer头,确保参数完整:

var clientId = "myClientID";
var clientSecret = "mySecret";
var refreshToken = await HttpContext.GetTokenAsync("refresh_token");

// scope参数需和初始认证时一致,否则可能返回权限不足的令牌
var requestData = new List<KeyValuePair<string, string>>
{
    new KeyValuePair<string, string>("client_id", clientId),
    new KeyValuePair<string, string>("client_secret", clientSecret),
    new KeyValuePair<string, string>("grant_type", "refresh_token"),
    new KeyValuePair<string, string>("refresh_token", refreshToken),
    new KeyValuePair<string, string>("scope", "openid profile email") // 根据实际权限调整
};

3. 发送POST请求并处理响应

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
    var response = await client.PostAsync(tokenEndpoint, new FormUrlEncodedContent(requestData));
    
    // 先检查响应状态,便于排查问题
    if (!response.IsSuccessStatusCode)
    {
        var errorContent = await response.Content.ReadAsStringAsync();
        // 添加错误日志或处理逻辑
        throw new HttpRequestException($"刷新令牌失败: {errorContent}");
    }
    
    var tokenResponse = await response.Content.ReadFromJsonAsync<dynamic>();
    
    // 提取新令牌
    var newAccessToken = tokenResponse.access_token;
    var newRefreshToken = tokenResponse.refresh_token;
    
    // 更新HttpContext中的令牌
    var authResult = await HttpContext.AuthenticateAsync();
    authResult.Properties.UpdateTokenValue("access_token", newAccessToken);
    authResult.Properties.UpdateTokenValue("refresh_token", newRefreshToken);
    await HttpContext.SignInAsync(authResult.Principal, authResult.Properties);
}

额外注意事项

  • 刷新令牌生命周期:Azure AD v2.0的刷新令牌默认有效期90天,若用户长期不活动或令牌被撤销,刷新会失败,需引导用户重新登录。
  • 客户端类型适配:Web应用(机密客户端)使用client_secret是正确的;SPA等公共客户端不应使用client_secret,需改用其他验证方式。
  • 令牌安全存储:确保刷新令牌被安全存储,避免泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 08:33:29