跨域连接Dynamics CRM Web API遇401未授权问题求助
Alright, let's break down your problem step by step—you're dealing with two linked issues: missing CORS headers causing cross-domain blocks, and 401 errors because you can't prompt users for authentication. Here's the most secure, maintainable way to solve this:
1. Use a .NET Core Reverse Proxy (Best Solution)
The cleanest fix for CORS is to avoid cross-domain calls entirely by routing requests through your own domain1.com backend. This also keeps sensitive auth logic hidden from the frontend.
Step 1.1 Set Up the Proxy with Yarp
Yarp is Microsoft's official reverse proxy library for .NET Core—super easy to configure:
- Install the NuGet package:
dotnet add package Yarp.ReverseProxy - Update your
Program.csto configure CORS and the proxy:var builder = WebApplication.CreateBuilder(args); // Configure CORS to allow your frontend (skip if frontend is on the same domain) builder.Services.AddCors(options => { options.AddPolicy("AllowFrontend", policy => policy.WithOrigins("https://domain1.com") .AllowAnyHeader() .AllowAnyMethod()); }); // Add Yarp proxy and load config from appsettings builder.Services.AddReverseProxy() .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); var app = builder.Build(); app.UseCors("AllowFrontend"); app.MapReverseProxy(); app.Run(); - Add proxy rules to
appsettings.json:"ReverseProxy": { "Routes": { "crm-api-route": { "ClusterId": "crm-cluster", "Match": { "Path": "/crm-api/{**catch-all}" } } }, "Clusters": { "crm-cluster": { "Destinations": { "crm-api": { "Address": "https://domain2.com/api/data/v9.2/" } } } } }
Now your frontend can call https://domain1.com/crm-api/accounts instead of the direct CRM URL—no more CORS issues.
Step 1.2 Authenticate with a Service Principal (No User Login Required)
To avoid prompting users for auth, use an Azure AD Service Principal (a non-user identity) to get access tokens for the CRM API. This runs entirely in your backend.
- Create a Service Principal in Azure AD:
- Go to Azure Portal → Azure Active Directory → App Registrations → New Registration
- Note down the Client ID, Tenant ID, and create a Client Secret (under "Certificates & Secrets")
- Assign CRM Permissions:
- In the app registration, go to "API Permissions" → Add a permission → Select "Dynamics CRM"
- Choose Application Permissions (not Delegated) and pick the minimum permissions you need (e.g.,
crm.read.all,crm.write.all) - Click "Grant admin consent for [Your Tenant]" to activate the permissions
- Add Token Authentication to the Proxy:
- Install the MSAL library:
dotnet add package Microsoft.Identity.Client - Update the proxy configuration in
Program.csto inject the access token into requests:builder.Services.AddReverseProxy() .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")) .AddTransforms(async context => { context.AddRequestTransform(async transformContext => { // Initialize MSAL client var msalClient = new ConfidentialClientApplicationBuilder( builder.Configuration["AzureAd:ClientId"], $"https://login.microsoftonline.com/{builder.Configuration["AzureAd:TenantId"]}/v2.0") .WithClientSecret(builder.Configuration["AzureAd:ClientSecret"]) .Build(); // Request token for CRM API (use your CRM's resource URL + /.default) var scopes = new[] { "https://domain2.com/.default" }; var authResult = await msalClient.AcquireTokenForClient(scopes).ExecuteAsync(); // Add Bearer token to proxy request transformContext.ProxyRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken); }); }); - Add Azure AD settings to
appsettings.json:"AzureAd": { "ClientId": "your-service-principal-client-id", "ClientSecret": "your-service-principal-client-secret", "TenantId": "your-azure-ad-tenant-id" }
- Install the MSAL library:
2. Direct CORS Configuration (Not Recommended)
If you absolutely can't use a proxy, you can configure CORS directly in the Azure AD app registration linked to your Dynamics CRM:
- Go to Azure Portal → App Registrations → Find the app linked to your CRM (usually named "Microsoft Dynamics CRM")
- Navigate to "Authentication" → Under "CORS", add
https://domain1.comto the allowed origins list - Warning: This exposes your CRM API directly to external domains, and you can't safely handle auth in the frontend (you'd have to expose sensitive credentials, which is a major security risk). Stick with the proxy approach for production.
Key Security Notes
- Never expose your Service Principal's Client Secret in frontend code—keep all auth logic server-side
- Assign the least possible permissions to the Service Principal (follow the principle of least privilege)
- Ensure your Dynamics CRM environment allows Service Principal access (check Power Platform admin center if needed)
内容的提问来源于stack exchange,提问作者Filipe Souza

