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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 22:15:03