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

跨域连接Dynamics CRM Web API遇401未授权问题求助

Fixing CORS & 401 Unauthorized for Dynamics CRM Web API from .NET Core Frontend

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.cs to 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.

  1. 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")
  2. 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
  3. Add Token Authentication to the Proxy:
    • Install the MSAL library: dotnet add package Microsoft.Identity.Client
    • Update the proxy configuration in Program.cs to 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"
      }
      

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.com to 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:18