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

如何为使用WAM代理的Azure应用刷新访问令牌?

问题分析与解决方案

一、当前400错误的可能原因及修复

你的代码返回400错误,大概率是以下问题导致的:

  • 缺少scope参数:Azure AD v2.0令牌端点刷新令牌时,必须指定scope参数,且该scope必须与获取原始刷新令牌时使用的scope一致(或为其子集)。比如当初获取令牌时用了User.Read,刷新时也要带上这个scope。
  • 重定向URI配置问题:要确保Azure应用注册中已经添加了ms-appx-web://microsoft.aad.brokerplugin/{ClientId}这个URI,并且你的应用被标记为公共客户端(WAM属于公共客户端场景,不需要客户端密钥)。
  • 端点URL验证:确认Instance的值正确,比如全球版是https://login.microsoftonline.com/,中国区是https://login.partner.microsoftonline.cn/,拼接后的完整URL格式应为https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token。

修复后的代码需添加scope参数,示例如下:

public async Task<string> RefreshTokenAsync(string refreshToken, string Tenant, string Instance, string ClientId, string scope)
{
    using (var client = new HttpClient())
    {
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "refresh_token"),
            new KeyValuePair<string, string>("client_id", ClientId),
            new KeyValuePair<string, string>("refresh_token", refreshToken),
            new KeyValuePair<string, string>("redirect_uri", "ms-appx-web://microsoft.aad.brokerplugin/" + ClientId),
            new KeyValuePair<string, string>("scope", scope) // 添加scope参数
        });

        var response = await client.PostAsync($"{Instance}{Tenant}/oauth2/v2.0/token", content);

        if (response.IsSuccessStatusCode)
        {
            var responseJson = await response.Content.ReadAsStringAsync();
            var responseObject = JsonConvert.DeserializeObject<TokenResponse>(responseJson);
            return responseObject.AccessToken;
        }
        else
        {
            string errorContent = await response.Content.ReadAsStringAsync();
            MessageBox.Show(errorContent, "Error", MessageBoxButton.OK);
            return string.Empty;
        }
    }
}

public class TokenResponse
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
    [JsonProperty("refresh_token")] // 建议保留,刷新后会返回新的刷新令牌
    public string RefreshToken { get; set; }
}

二、更简单的令牌刷新方法:使用MSAL.NET

手动编写HTTP请求容易出错,推荐使用官方的**MSAL.NET(Microsoft.Identity.Client)**库,它原生支持WAM集成,自动处理令牌缓存、刷新、过期等逻辑,无需手动调用令牌端点。

实现步骤:

  1. 安装MSAL.NET NuGet包:Microsoft.Identity.Client
  2. 初始化公共客户端应用实例(支持WAM):
private IPublicClientApplication _pca;

public void InitializeMsal(string ClientId, string Tenant)
{
    _pca = PublicClientApplicationBuilder.Create(ClientId)
        .WithAuthority($"https://login.microsoftonline.com/{Tenant}")
        .WithBroker(true) // 启用WAM
        .WithRedirectUri("ms-appx-web://microsoft.aad.brokerplugin/" + ClientId) // 指定WAM重定向URI
        .Build();
}
  1. 刷新令牌(自动从缓存获取或刷新):
public async Task<string> GetAccessTokenAsync(string[] scopes)
{
    // 尝试从缓存获取令牌
    var accounts = await _pca.GetAccountsAsync();
    var result = await _pca.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
        .ExecuteAsync();
    
    return result.AccessToken;
}

当缓存中的令牌过期时,MSAL会自动触发刷新流程,同时更新缓存中的刷新令牌,大幅简化开发工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:04:51