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

从ADAL迁移至MSAL React后调用.NET Core 2.1 API时遭遇401未授权错误

Troubleshooting 401 Unauthorized When Migrating from ADAL to MSAL (React + .NET Core 2.1)

Hey there, let’s work through why your API is rejecting the MSAL-generated token—this is a common pitfall when moving from ADAL to MSAL, so let’s break down the most likely fixes step by step:

1. Check the Token’s Audience (aud Claim)

MSAL uses scopes instead of the resource IDs that ADAL relied on. If your React app is requesting a scope that doesn’t match your API’s identifier, the API will immediately reject the token.

  • Decode your token with a local tool like jwt.ms (you can use it in your browser without sending data to external servers) and look for the aud claim. It must exactly match your API’s Application ID URI (found in Azure AD > Your API App > Expose an API > Application ID URI).
  • Update your React MSAL scope request to target the API properly. For example:
    const tokenRequest = {
      scopes: ["api://your-api-client-id/.default"]
    };
    

2. Fix the .NET Core 2.1 Authentication Configuration

Your current AddAzureAdBearer setup might be missing critical details needed to validate MSAL’s v2 tokens. .NET Core 2.1’s Azure AD integration often needs explicit tweaks for v2 token support:

  • First, ensure you’re using the Microsoft.AspNetCore.Authentication.AzureAD.UI NuGet package (update it to a version compatible with v2 tokens if needed).
  • Adjust your appsettings.json to include your API’s own Client ID (this is easy to overlook!) and refine the issuer settings:
    "AzureAd": {
      "Instance": "https://login.microsoftonline.com/",
      "TenantId": "common",
      "ClientId": "your-api-client-id", // Critical: Use the API's client ID here
      "ValidClientIds": ["ui-client-id-1", "ui-client-id-2"],
      "AllowedIssuers": ["https://login.microsoftonline.com/{user-tenant-id}/v2.0"]
    }
    
  • Replace the generic AddAzureAdBearer helper with explicit JWT bearer configuration to handle v2 tokens properly:
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = $"{configuration["AzureAd:Instance"]}{configuration["AzureAd:TenantId"]}/v2.0";
            options.Audience = configuration["AzureAd:ClientId"]; // API's own client ID
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuers = configuration.GetSection("AzureAd:AllowedIssuers").Get<string[]>(),
                ValidateAudience = true,
                ValidAudience = configuration["AzureAd:ClientId"],
                ValidateLifetime = true,
                // For multi-tenant apps using "common", you may need custom issuer validation instead of hardcoding
                // ValidateIssuer = false,
                // IssuerValidator = (issuer, token, parameters) => { /* Add logic to accept valid tenant issuers */ }
            };
        });
    

3. Confirm API Permissions Are Granted

Even if you added your UI client to the API’s "Authorized client applications" list, you need to ensure permissions are actually granted:

  • Go to Azure AD > Your API App > Expose an API > Authorized client applications. Double-check that your UI client’s entry has the correct scopes enabled.
  • For delegated permissions in multi-tenant apps, a tenant admin must grant consent. You can test this by having an admin visit a consent URL like:
    https://login.microsoftonline.com/common/adminconsent?client_id=your-ui-client-id&scope=api://your-api-client-id/.default

4. Ensure MSAL Returns an Access Token (Not Just an ID Token)

MSAL for React defaults to ID tokens for authentication, but you need an access token to call APIs. Make sure you’re using token-acquisition methods instead of just login methods:

const { instance } = useMsal();
const activeAccount = instance.getActiveAccount();

const getAccessToken = async () => {
  try {
    const response = await instance.acquireTokenSilent({
      account: activeAccount,
      scopes: ["api://your-api-client-id/.default"]
    });
    return response.accessToken;
  } catch (error) {
    // Fallback to popup if silent acquisition fails
    const response = await instance.acquireTokenPopup({
      scopes: ["api://your-api-client-id/.default"]
    });
    return response.accessToken;
  }
};

5. Enable Detailed Logging for Debugging

If you’re still stuck, turn on verbose logging in your API to see exactly where token validation fails:
In appsettings.json:

"Logging": {
  "LogLevel": {
    "Microsoft.AspNetCore.Authentication": "Debug",
    "Microsoft.IdentityModel.Tokens": "Debug"
  }
}

Run the API and check the logs—they’ll tell you if the issue is an invalid audience, mismatched issuer, expired token, or something else.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:42:32