C#如何利用Azure AD认证后redirect_uri返回的授权码生成AccessToken
排查和实现方案
- 先确认以下最常见的失败原因,排除配置类问题:
- 回调地址
redirect_uri必须和你发起身份认证请求时传的参数完全一致,包括协议头(http/https)、末尾斜杠、大小写,只要有一处不同就会请求失败 - 确认应用注册里生成的客户端密钥未过期,且填写的是正确的客户端ID、租户ID
- 授权码
code只能使用一次,且有效期极短,拿到后必须立刻发起换令牌请求,重复使用会直接报错 - 换令牌时传的
scope要和发起认证请求时的scope保持一致
- 回调地址
原生HttpClient实现(无额外SDK依赖)
using System.Net.Http; using System.Collections.Generic; using System.Threading.Tasks; using System.Text.Json; public async Task<string> GetAccessTokenByCode(string code) { // 替换为你自己的Azure AD配置 var tenantId = "你的Azure AD租户ID"; var clientId = "应用注册的客户端ID"; var clientSecret = "应用注册生成的客户端密钥"; var redirectUri = "你在Azure AD中配置的回调地址,和认证请求时的完全一致"; var scope = "你申请的权限,示例:User.Read openid offline_access"; using var httpClient = new HttpClient(); var requestParams = new FormUrlEncodedContent(new Dictionary<string, string> { ["client_id"] = clientId, ["client_secret"] = clientSecret, ["grant_type"] = "authorization_code", ["code"] = code, ["redirect_uri"] = redirectUri, ["scope"] = scope }); var response = await httpClient.PostAsync($"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token", requestParams); var responseContent = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { // 这里打印responseContent可以拿到明确的错误原因,比如code无效、回调地址不匹配等 throw new HttpRequestException($"令牌获取失败,错误信息:{responseContent}"); } using var jsonDoc = JsonDocument.Parse(responseContent); return jsonDoc.RootElement.GetProperty("access_token").GetString(); // 如需刷新令牌可以同时取refresh_token字段存储 }
MSAL SDK实现(官方推荐,无需手动处理请求细节)
using Microsoft.Identity.Client; public async Task<string> GetAccessTokenByMsal(string code) { // 替换为你自己的Azure AD配置 var tenantId = "你的Azure AD租户ID"; var clientId = "应用注册的客户端ID"; var clientSecret = "应用注册生成的客户端密钥"; var redirectUri = "你在Azure AD中配置的回调地址"; var scopes = new[] { "User.Read", "openid", "offline_access" }; // 替换为实际需要的权限 var confidentialClient = ConfidentialClientApplicationBuilder .Create(clientId) .WithClientSecret(clientSecret) .WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}")) .WithRedirectUri(redirectUri) .Build(); var tokenResult = await confidentialClient.AcquireTokenByAuthorizationCode(scopes, code) .ExecuteAsync(); return tokenResult.AccessToken; }
调试提示:如果请求失败,优先看接口返回的错误码,比如
redirect_uri_mismatch就是回调地址不匹配,invalid_grant就是code无效/过期,invalid_client就是客户端ID/密钥错误,都可以直接定位问题。
内容的提问来源于stack exchange,提问作者Sunil M
相关产品推荐
相关产品推荐

