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

如何使用MSAL从.NET MAUI应用调用Azure AD B2C认证的API

使用MSAL实现.NET MAUI对Azure AD B2C保护的API调用

核心思路:让MSAL自动管理令牌并注入请求头

MSAL的AcquireTokenSilent方法会自动处理令牌的获取与刷新,配合HttpClient的委托处理程序,就能实现请求头的自动注入,完全替代手动添加Bearer token的操作。

步骤1:初始化MSAL客户端

确保.NET MAUI项目中MSAL客户端配置包含目标API的权限范围(格式通常为https://{租户名}.b2clogin.com/{租户名}.onmicrosoft.com/api/{权限名}):

var pca = PublicClientApplicationBuilder
    .Create("你的客户端ID")
    .WithB2CAuthority("https://{租户名}.b2clogin.com/tfp/{租户名}.onmicrosoft.com/{你的B2C策略名}")
    .WithRedirectUri("msal{客户端ID}://auth") // .NET MAUI默认重定向URI
    .Build();

步骤2:实现令牌注入的Http委托处理器

自定义DelegatingHandler,在请求发送前自动获取令牌并添加到授权头:

public class MsalAuthHandler : DelegatingHandler
{
    private readonly IPublicClientApplication _pca;
    private readonly string[] _apiScopes;

    public MsalAuthHandler(IPublicClientApplication pca, string[] apiScopes)
    {
        _pca = pca;
        _apiScopes = apiScopes;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var accounts = await _pca.GetAccountsAsync();
        var currentAccount = accounts.FirstOrDefault();

        if (currentAccount != null)
        {
            try
            {
                // 静默获取令牌,MSAL自动处理过期刷新
                var tokenResult = await _pca.AcquireTokenSilent(_apiScopes, currentAccount)
                    .ExecuteAsync(cancellationToken);
                
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken);
            }
            catch (MsalUiRequiredException)
            {
                // 静默获取失败(如令牌过期且无法刷新、会话失效),触发交互式登录
                var interactiveResult = await _pca.AcquireTokenInteractive(_apiScopes)
                    .WithAccount(currentAccount)
                    .ExecuteAsync(cancellationToken);
                
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", interactiveResult.AccessToken);
            }
        }

        return await base.SendAsync(request, cancellationToken);
    }
}

步骤3:注册服务与HttpClient

在MauiProgram.cs中,将MSAL客户端和自定义处理器注册为依赖注入服务:

builder.Services.AddSingleton<IPublicClientApplication>(sp =>
{
    return PublicClientApplicationBuilder
        .Create("你的客户端ID")
        .WithB2CAuthority("https://{租户名}.b2clogin.com/tfp/{租户名}.onmicrosoft.com/{你的B2C策略名}")
        .WithRedirectUri("msal{客户端ID}://auth")
        .Build();
});

builder.Services.AddHttpClient("ProtectedApiClient", client =>
{
    client.BaseAddress = new Uri("你的API基础地址/");
})
.AddHttpMessageHandler(sp =>
{
    var pca = sp.GetRequiredService<IPublicClientApplication>();
    var apiScopes = new[] { "https://{租户名}.b2clogin.com/{租户名}.onmicrosoft.com/api/access_as_user" };
    return new MsalAuthHandler(pca, apiScopes);
});

步骤4:调用API(GET/POST示例)

通过依赖注入获取命名HttpClient,直接发起请求即可,无需手动处理令牌:

private readonly IHttpClientFactory _httpClientFactory;

public YourViewModel(IHttpClientFactory httpClientFactory)
{
    _httpClientFactory = httpClientFactory;
}

// GET请求示例
public async Task FetchApiDataAsync()
{
    var client = _httpClientFactory.CreateClient("ProtectedApiClient");
    var response = await client.GetAsync("api/你的接口路径");
    
    if (response.IsSuccessStatusCode)
    {
        var data = await response.Content.ReadFromJsonAsync<你的数据模型>();
        // 处理返回数据
    }
}

// POST请求示例
public async Task SubmitDataAsync(你的数据模型 model)
{
    var client = _httpClientFactory.CreateClient("ProtectedApiClient");
    var response = await client.PostAsJsonAsync("api/你的接口路径", model);
    
    if (response.IsSuccessStatusCode)
    {
        // 处理成功逻辑
    }
}

关键注意事项

  • 权限配置:确保Azure AD B2C中已为API注册对应权限,且客户端应用已被授予该权限。
  • 异常处理:MsalUiRequiredException是核心异常,需在此处触发交互式登录流程,引导用户重新认证。
  • 令牌缓存:MSAL会自动维护令牌缓存,包括刷新令牌的使用,无需手动存储或管理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:05:03