从ADAL迁移至MSAL React后调用.NET Core 2.1 API时遭遇401未授权错误
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
audclaim. 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.UINuGet package (update it to a version compatible with v2 tokens if needed). - Adjust your
appsettings.jsonto 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
AddAzureAdBearerhelper 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

