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

.NET MAUI应用添加[Authorize]后API数据加载失败问题

解决.NET MAUI应用调用带[Authorize]的API无法加载数据的问题

问题核心是:给API控制器添加[Authorize]后,所有请求必须携带有效的JWT令牌才能通过授权验证,而你的MAUI应用当前没有在请求中附加该令牌,导致API返回401未授权,最终无法加载数据。以下是分步解决方案:

一、先确认API端的JWT认证配置是否正确

  1. 检查appsettings.json中的Microsoft Identity配置是否完整,示例配置如下:
"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "Domain": "your-domain.onmicrosoft.com",
  "TenantId": "your-tenant-id",
  "ClientId": "your-api-client-id",
  "Scopes": "api://your-api-client-id/access_as_user"
}
  1. 确认API启动代码中AddMicrosoftIdentityWebApi已正确绑定配置,你的现有代码这部分逻辑正确,但要确保配置文件中的值和Microsoft Entra ID(原Azure AD)里的注册应用信息完全匹配。

二、修改MAUI应用,在请求中附加JWT令牌

1. 集成MSAL库实现用户登录获取令牌

在MAUI项目中安装Microsoft.Identity.Client NuGet包,然后实现登录逻辑:

using Microsoft.Identity.Client;

public class AuthService
{
    private readonly IPublicClientApplication _msalClient;
    private const string ClientId = "your-maui-app-client-id"; // 对应Entra ID中注册的MAUI应用ID
    private const string TenantId = "your-tenant-id";
    private const string ApiScope = "api://your-api-client-id/access_as_user"; // 对应API的访问范围

    public AuthService()
    {
        _msalClient = PublicClientApplicationBuilder
            .Create(ClientId)
            .WithTenantId(TenantId)
            .WithRedirectUri($"msal{ClientId}://auth") // MAUI应用的重定向URI,需在Entra ID中配置
            .Build();
    }

    public async Task<string> GetAccessTokenAsync()
    {
        var accounts = await _msalClient.GetAccountsAsync();
        AuthenticationResult result;

        try
        {
            // 尝试静默获取令牌(用户已登录时)
            result = await _msalClient.AcquireTokenSilent(new[] { ApiScope }, accounts.FirstOrDefault())
                .ExecuteAsync();
        }
        catch (MsalUiRequiredException)
        {
            // 静默失败,弹出登录界面
            result = await _msalClient.AcquireTokenInteractive(new[] { ApiScope })
                .ExecuteAsync();
        }

        return result.AccessToken;
    }
}

2. 封装HTTP客户端,自动附加令牌

创建自定义HTTP客户端,在发送请求前自动添加Authorization头:

public class ApiClient
{
    private readonly HttpClient _httpClient;
    private readonly AuthService _authService;

    public ApiClient(HttpClient httpClient, AuthService authService)
    {
        _httpClient = httpClient;
        _authService = authService;
        _httpClient.BaseAddress = new Uri("https://your-api-base-url/api/v1/");
    }

    public async Task<T> GetAsync<T>(string endpoint)
    {
        var token = await _authService.GetAccessTokenAsync();
        _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
        
        var response = await _httpClient.GetAsync(endpoint);
        response.EnsureSuccessStatusCode(); // 抛出HTTP错误,方便调试
        return await response.Content.ReadFromJsonAsync<T>();
    }

    // 同理实现Post/Put/Delete等请求方法
}

3. 在MAUI的DI容器中注册服务

在MauiProgram.cs中添加服务注册:

builder.Services.AddSingleton<AuthService>();
builder.Services.AddHttpClient<ApiClient>();

4. 在MAUI页面中使用ApiClient获取数据

public class ActivitiesPage : ContentPage
{
    private readonly ApiClient _apiClient;

    public ActivitiesPage(ApiClient apiClient)
    {
        _apiClient = apiClient;
        LoadActivities();
    }

    private async void LoadActivities()
    {
        try
        {
            var activities = await _apiClient.GetAsync<IEnumerable<ActivitiesModel>>("Activities/all");
            // 将数据绑定到UI控件
        }
        catch (Exception ex)
        {
            // 处理错误,如登录失败、API请求异常等
            await DisplayAlert("错误", ex.Message, "确定");
        }
    }
}

三、调试与验证技巧

  • 用Postman测试API:手动获取JWT令牌(可通过Entra ID测试工具或MSAL生成),在请求头中添加Authorization: Bearer {token},调用API确认是否正常返回数据,排除API端配置问题。
  • 查看API日志:在开发环境中启用详细日志,查看授权失败的具体原因(如令牌无效、缺少必要Scope、令牌过期等)。
  • 抓包检查MAUI请求:使用Charles或Fiddler抓包,确认MAUI发送的请求中是否包含正确的Authorization头。

四、可选:允许部分接口匿名访问

如果某些公开接口不需要授权,可在对应的Action上添加[AllowAnonymous]属性,比如:

[HttpGet]
[Route("all")]
[AllowAnonymous] // 允许匿名访问该接口
public async Task<ActionResult<IEnumerable<ActivitiesEntity>>> GetActivities()
{
    // ... 原有代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:11:07