Azure AD OpenID Connect刷新AccessToken失败,求正确请求方式
Azure AD OIDC认证刷新令牌请求错误修正
你的代码存在几个关键问题,导致刷新令牌请求失败:
核心错误点
- 使用了错误的Token端点:你当前用的是OIDC发现文档地址(
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration),但实际刷新令牌需要调用该文档里返回的token_endpoint字段对应的URL,而非发现文档本身。 - 多余的Bearer授权头:刷新令牌请求不需要携带原access token的Bearer授权,Azure AD的token端点仅需通过表单参数验证客户端身份(client_id+client_secret)和刷新令牌。
- 可能缺失的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
相关产品推荐
相关产品推荐

