如何在ASP.net Core WebAPI中启用CORS


189

我想做什么

我有一个托管在Azure免费计划上的后端ASP.Net Core Web API(源代码:https : //github.com/killerrin/Portfolio-Backend)。

我也有一个客户网站,我想使用该API。客户端应用程序不会托管在Azure上,而是托管在Github Pages或我有权访问的另一个Web托管服务上。因此,域名将无法排列。

考虑到这一点,我需要在Web API端启用CORS,但是我已经尝试了几乎所有内容几个小时,并且它拒绝工作。

我如何进行客户端设置 它只是一个用React.js编写的简单客户端。我正在通过Jquery中的AJAX调用API。React网站可以正常工作,所以我不知道。正如我在尝试1中确认的那样,对Jquery API的调用有效。这是我进行调用的方式

    var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
    //alert(username + "|" + password + "|" + apiUrl);
    $.ajax({
        url: apiUrl,
        type: "POST",
        data: {
            username: username,
            password: password
        },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            var authenticatedUser = JSON.parse(response);
            //alert("Data Loaded: " + authenticatedUser);
            if (onComplete != null) {
                onComplete(authenticatedUser);
            }
        },
        error: function (xhr, status, error) {
            //alert(xhr.responseText);
            if (onComplete != null) {
                onComplete(xhr.responseText);
            }
        }
    });

我尝试过的


尝试1-正确的方式

https://docs.microsoft.com/zh-cn/aspnet/core/security/cors

我已经在Microsoft网站上将此教程按照T进行了操作,尝试了在Startup.cs中全局启用它,在每个控制器上进行设置以及在每个Action上进行尝试的所有3个选项。

按照此方法,跨域可以工作,但只能在单个控制器上的单个Action上执行(POST到AccountController)。对于其他所有内容,Microsoft.AspNetCore.Cors中间件都拒绝设置标头。

Microsoft.AspNetCore.Cors通过NUGET 安装,版本为1.1.2

这是我在Startup.cs中设置的方式

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Cors
        services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        // Add framework services.
        services.AddMvc();
        services.Configure<MvcOptions>(options =>
        {
            options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
        });

        ...
        ...
        ...
    }

    // This method gets called by the runtime. Use this method to configure 
    //the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        // Enable Cors
        app.UseCors("MyPolicy");

        //app.UseMvcWithDefaultRoute();
        app.UseMvc();

        ...
        ...
        ...
    }

如您所见,我正在按照指示进行所有操作。我两次都在MVC之前添加了Cors,但在这种方法不起作用时,我尝试将[EnableCors("MyPolicy")]每个控制器都这样

[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

尝试2-暴力破解

https://andrewlock.net/adding-default-security-headers-in-asp-net-core/

在尝试了上一个尝试几个小时之后,我认为我会尝试通过手动设置标头,迫使它们在每个响应上运行来对它进行暴力破解。我在本教程之后进行了有关如何手动向每个响应添加标头的操作。

这些是我添加的标题

.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

这些是我尝试过的其他标头,但失败了

.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")

使用这种方法,可以正确应用跨站点标题,并且它们会显示在我的开发人员控制台和Postman中。但是,问题在于,虽然通过了Access-Control-Allow-Origin检查,但网络浏览器却出现了嘶哑的感觉(我相信)Access-Control-Allow-Headers声明时415 (Unsupported Media Type)

所以蛮力方法也不起作用


最后

有没有人让这件事奏效并可以伸出援手,或者只是能够向我指出正确的方向?


编辑

因此,为了使API调用能够通过,我不得不停止使用JQuery并切换为Pure Javascript XMLHttpRequest格式。

尝试1

我设法Microsoft.AspNetCore.Cors通过遵循MindingData的答案来工作,除了在ConfigureMethod中放置了app.UseCorsbefore app.UseMvc

另外,当与Javascript API解决方案混合使用时 options.AllowAnyOrigin(),通配符支持也开始起作用。

尝试2

因此,我设法使Attempt 2(强行强制执行)...工作,唯一的例外是通配符Access-Control-Allow-Origin不起作用,因此,我必须手动设置可以访问它的域。

这显然不是理想的,因为我只想向所有人开放此WebAPI,但是它至少在单独的站点上对我有用,这意味着这是一个开始

app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
    .AddDefaultSecurePolicy()
    .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
    .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
    .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));

2
对于您的415 (Unsupported Media Type)问题,请将Content-Type请求标头设置为application/json
Technetium

5
感谢您抽出宝贵的时间来写这样一个描述性问题。
user1007074

1
如果您正在使用Postman进行测试,请确保将Origin设置为*或用于请求标头设置,然后尝试1号即可。如果没有此标头,则不会在响应标头中返回Access-Control-Allow-Origin。
tala9999

Answers:


237

因为您有一个非常简单的CORS策略(允许来自XXX域的所有请求),所以无需使其变得如此复杂。首先尝试执行以下操作(CORS的非常基本的实现)。

如果尚未安装,请安装CORS nuget软件包。

Install-Package Microsoft.AspNetCore.Cors

在startup.cs的ConfigureServices方法中,添加CORS服务。

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(); // Make sure you call this previous to AddMvc
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

然后在startup.cs的Configure方法中,添加以下内容:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Make sure you call this before calling app.UseMvc()
    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}

现在去吧。策略适用于您希望针对不同操作(例如,不同的主机或不同的标头)使用不同的策略。对于您的简单示例,您确实不需要它。从这个简单的示例开始,然后根据需要进行调整。

进一步的阅读:http : //dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/


3
XMLHttpRequest无法加载andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication。对预检请求的响应未通过访问控制检查:所请求的资源上不存在“ Access-Control-Allow-Origin”标头。因此,不允许访问源' localhost:3000 '。响应有HTTP状态代码415
killerrin

7
当您注册时,这不太可能起作用 app.UseCors ``app.UseMvc()` 之后。中间件在他们注册的顺序执行

24
在Configure方法中,在app.UseMvc之前使用app.UseCors似乎有效。由于某种原因,顺序似乎很重要。
MrClan '17

1
对我来说,2.0中CORS的最大问题是它不会告诉您出了什么问题,只是默默地未能设置CORS标头。注意:请记住将所有必需的标头添加到策略中,否则它将失败(我具有内容类型)。此外,我奇怪的事情是CORS中间件不刹请求处理,只是在日志起源是不允许的,并通知..通行证进一步申请(中间件顺序是正确的)。
Andrii M4n0w4R

2
我必须启用options.DisableHttpsRequirement();它才能使其中任何一个起作用。似乎与https cors设置不适用。
迈克尔·布朗

206
  • ConfigureServices中添加 services.AddCors(); BEFORE services.AddMvc();。
  • 配置中添加UseCors

    app.UseCors(builder => builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());   
    app.UseMvc();

要点是app.UseCors在之前添加app.UseMvc()

确保在MVC之前声明CORS功能,以便在MVC管道获得控制并终止请求之前触发中间件。

在上述方法工作之后,您可以对其进行更改,将其配置为特定的起源以接受api调用,并避免让您的API向任何人开放

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
    {
        builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
    }));
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

在configure方法中,告诉CORS使用您刚创建的策略:

app.UseCors("ApiCorsPolicy");
app.UseMvc();

我刚刚找到了该主题的紧凑文章-https: //dzone.com/articles/cors-in-net-core-net-core-security-part-vi



17
作为一个好的“起点”,这确实应该获得更多的支持。以我超过25年的编码经验,总是很高兴知道如何打开闸门,以确保它确实“起作用”,然后根据需要关闭/保护事物。
Indy-Jones

4
只需提一下,与Configure()顺序相反,在此范围内并不是很重要ConfigureServices()
B12Toaster

我在“进一步阅读器”中使用了该链接,这些步骤解决了该错误。我不确定这些更改应该放在哪里(我认为是API)。链接确认应将它们放在API中。谢谢您的帮助。由于这个错误,我完全无法自拔。
理查德

1
仅供参考-CORS规范还指出,如果存在Access-Control-Allow-Credentials标头,则将原点设置为“ *”(所有原点)是无效的。意味着您不能AllowCredentials()AllowAnyOrigin()上述类似使用。要使用AllowCredentials()您需要设置WithOrigins()docs.microsoft.com/en-us/aspnet/core/security/...
尼克·德啤酒

27

我创建了自己的对我有用的中间件类,我认为.net核心中间件类有问题

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}

并在startup.cs中以这种方式使用

app.UseCorsMiddleware();

运行Access-Control-Allow-Origin的非常优雅的方式。
ArturPoniedziałek17年

这适用于WebAPI和MVC,并且没有依赖项,谢谢!

我对此也持怀疑态度,但这对我有用。我基本上尝试了其他所有方法来完成我可以在Internet上找到的方法,但是无论什么服务器都不会响应访问标头。这很棒。我正在运行aspnetcore 2.1。
乔丹

仅当客户端在请求中发送标头“ Origin”时,才应返回cors标头。在原始的CospMiddleware中,它看起来像这样:if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
Andrew Prigorshnev,

1
也许“ .net核心中间件类有问题”,因为在使用curl或类似的东西测试它时,您只是不添加标题“ Origin”。当您以js代码发出请求时,浏览器会自动添加此标头。
Andrew Prigorshnev,

17

就我而言,get根据MindingData的回答,只有请求才能很好地工作。对于其他类型的请求,您需要编写:

app.UseCors(corsPolicyBuilder =>
   corsPolicyBuilder.WithOrigins("http://localhost:3000")
  .AllowAnyMethod()
  .AllowAnyHeader()
);

不要忘记添加 .AllowAnyHeader()


同意Towhid的需要AllowAnyHeader()。如果HEADER的请求丢失了某些内容,它将使服务器接收OPTIONS请求。
冯(Rivon)'17

.AllowAnyHeader()为我做到了,我在飞行前响应时遇到了问题。
塔卡兹

11

为了扩展user8266077答案,我发现我仍然需要为用例提供.NET Core 2.1-preview中预检请求的 OPTIONS响应:

// https://stackoverflow.com/a/45844400
public class CorsMiddleware
{
  private readonly RequestDelegate _next;

  public CorsMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    // Added "Accept-Encoding" to this list
    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
    context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
    // New Code Starts here
    if (context.Request.Method == "OPTIONS")
    {
      context.Response.StatusCode = (int)HttpStatusCode.OK;
      await context.Response.WriteAsync(string.Empty);
    }
    // New Code Ends here

    await _next(context);
  }
}

然后在Startup.cs中启用中间件

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}

1
我建议以这种方式添加中间件:app.Use<CorsMiddleware>();
Albert221 '18

您可以替换这两个ligne:context.Response.StatusCode =(int)HttpStatusCode.OK; 等待context.Response.WriteAsync(string.Empty); 简单:return;
Hayha '18

1
扩展您对@ user8266077的回答:请注意,如果由于其他原因导致请求失败,则此中间件将引发异常,并且不会设置标头。这意味着在前端,即使完全不同,它仍然看起来像是CORS问题。我通过捕获任何异常await _next(context)并在发生这种情况时手动设置状态代码和响应来绕过此操作。我还必须将“授权”添加到Access-Control-Allow-Headers中,以使预检请求在需要响应的响应请求中起作用。
亚当

10

我在DAYS一直为此苦苦挣扎。

我终于通过移动它得到工作app.UseCors(CORS_POLICY);TOPConfigure()

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas

确保在> MVC之前声明CORS功能,因为在MVC完成请求之前必须应用标头。

<=即使我的应用程序未调用UseMVC(),移至UseCors()顶部仍可解决问题

也:

  • Microsoft.AspNetCore.Cors曾经是.Net Core 2和更低版本中必需的NuGet软件包;现在,它自动成为.Net Core 3及更高版本中Microsoft.AspNetCore的一部分。
  • builder.AllowAnyOrigin().AllowCredentials() CORS选项现在在.Net Core 3和更高版本中互斥
  • CORS政策似乎要求Angular使用来调用服务器https。无论.Net Core服务器的CORS配置如何,http URL似乎都会给出CORS错误。例如,http://localhost:52774/api/Contacts将给出CORS错误;只需将网址更改为https://localhost:44333/api/Contacts有效即可。

补充说明

就我而言,CORS在我移至app.UseCors()上方时才起作用app.UseEndpoints(endpoints => endpoints.MapControllers())


2
如果您使用的是Net Core 3,这应该是答案。感谢您的救命!
加拿大Wan

2
“使用端点路由,必须将CORS中间件配置为在对UseRouting和UseEndpoints的调用之间执行。错误的配置将导致中间件停止正确运行。” 这里docs.microsoft.com/en-us/aspnet/core/security/...
马克Schultheiss

“使用端点路由,必须将CORS中间件配置为在对UseRouting和UseEndpoints的调用之间执行。错误的配置将导致中间件停止正确运行。” 这里docs.microsoft.com/en-us/aspnet/core/security/...
马克Schultheiss

10
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {      
       app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
    }

.SetIsOriginAllowed((host)=> true)为我解决了这个问题。
JensB

哇,所以我完全希望其他答案能在这个只有3票的小家伙面前起作用。但是我细心地尝试了每个,...我一时兴起,为你而去,并且奏效了。谢谢
robertotomás

7

以上过程均无济于事,然后我阅读解决了此问题的文章

下面是代码。

public void ConfigureServices(IServiceCollection services)
{
    // Add service and create Policy with options
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials() );
    });


    services.AddMvc(); 
}

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

在我的行动方法之上

[EnableCors("CorsPolicy")]

2
这可能是一个坏主意:您不应在同一应用程序中混合使用中间件(app.UseCors()[EnableCors()]。您应该使用其中一个,但不能同时使用:docs.microsoft.com/en-us/aspnet/core/security/…Use the [EnableCors] attribute or middleware, not both in the same app.
FoggyDay

4

尝试jQuery.support.cors = true;在Ajax调用之前添加

也可能是您发送到API的数据很奇怪,

尝试添加以下JSON函数

        var JSON = JSON || {};

    // implement JSON.stringify serialization
    JSON.stringify = JSON.stringify || function (obj) {

        var t = typeof (obj);
        if (t != "object" || obj === null) {

            // simple data type
            if (t == "string") obj = '"' + obj + '"';
            return String(obj);

        }
        else {

            // recurse array or object
            var n, v, json = [], arr = (obj && obj.constructor == Array);

            for (n in obj) {
                v = obj[n]; t = typeof (v);

                if (t == "string") v = '"' + v + '"';
                else if (t == "object" && v !== null) v = JSON.stringify(v);

                json.push((arr ? "" : '"' + n + '":') + String(v));
            }

            return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
        }
    };

    // implement JSON.parse de-serialization
    JSON.parse = JSON.parse || function (str) {
        if (str === "") str = '""';
        eval("var p=" + str + ";");
        return p;
    };

然后在您的数据中:对象将其更改为

    data: JSON.stringify({
        username: username,
        password: password
    }),

谢谢你的帮助。结合每个人的答案后,肯定会利用答案的一部分来找出最终的解决方案
killerrin

4

最简单的解决方案是添加

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseCors(options => options.AllowAnyOrigin());

        app.UseHttpsRedirection();
        app.UseMvc();
    }

到Startup.cs。


3

我认为如果您使用自己的CORS中间件,则需要通过检查原始标头来确保它确实是CORS请求。

 public class CorsMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;
    private readonly ILogger<CorsMiddleware> _logger;

    public CorsMiddleware(RequestDelegate next, IMemoryCache cache, ILogger<CorsMiddleware> logger)
    {
        _next = next;
        _cache = cache;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context, IAdministrationApi adminApi)
    {
        if (context.Request.Headers.ContainsKey(CorsConstants.Origin) || context.Request.Headers.ContainsKey("origin"))
        {
            if (!context.Request.Headers.TryGetValue(CorsConstants.Origin, out var origin))
            {
                context.Request.Headers.TryGetValue("origin", out origin);
            }

            bool isAllowed;
            // Getting origin from DB to check with one from request and save it in cache 
            var result = _cache.GetOrCreateAsync(origin, async cacheEntry => await adminApi.DoesExistAsync(origin));
            isAllowed = result.Result.Result;

            if (isAllowed)
            {
                context.Response.Headers.Add(CorsConstants.AccessControlAllowOrigin, origin);
                context.Response.Headers.Add(
                    CorsConstants.AccessControlAllowHeaders,
                    $"{HeaderNames.Authorization}, {HeaderNames.ContentType}, {HeaderNames.AcceptLanguage}, {HeaderNames.Accept}");
                context.Response.Headers.Add(CorsConstants.AccessControlAllowMethods, "POST, GET, PUT, PATCH, DELETE, OPTIONS");

                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("CORS with origin {Origin} was handled successfully", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                await _next(context);
            }
            else
            {
                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("Preflight CORS request with origin {Origin} was declined", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                _logger.LogInformation("Simple CORS request with origin {Origin} was declined", origin);
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                return;
            }
        }

        await _next(context);
    }

非常感谢你。我差点疯了,问自己为什么Access-Control-Allow-Origin标头不是服务器发出的。实际上,我是通过邮递员发送的请求而没有Origin标题。这挽救了我的一天!(或者至少是我的
前夕

2

根据您在MindingData答案中的评论,它与您的CORS无关,它工作正常。

您的Controller动作返回了错误的数据。HttpCode 415的意思是“不受支持的媒体类型”。当您将错误的格式传递给控制器​​(即,将XML传递给仅接受json的控制器)或返回错误的类型(在声明为仅返回xml的控制器中返回Xml)时,就会发生这种情况。

稍后再检查[Produces("...")]您的操作是否存在属性


谢谢你的帮助。尝试了一种新的解决方案,并播放了json,并将其发送出去,在我将其字符串化并使其正常工作后,它可以正常工作
killerrin

2

对我来说,它与我使用的代码无关。对于Azure,我们必须进入App Service的设置,在侧面菜单上输入“ CORS”。在那里,我必须添加要从中请求内容的域。一旦我拥有了它,一切都会变得神奇。


2

在launchSettings.json中的iisSettings下,将anonymousAuthentication设置为true:

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:4200/",
      "sslPort": 0
    }
  }

然后,在Startup.cs中的ConfigureServices下,在services.AddMvc之前,添加:

services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
    builder
        .AllowAnyOrigin()
        .WithHeaders(HeaderNames.AccessControlAllowHeaders, "Content-Type")
        .AllowAnyMethod()
        .AllowCredentials();
}));

然后在configure方法中,在app.UseMvc()之前添加:

app.UseCors("ApiCorsPolicy");

这样做对我有用,我最初将我的项目设置为Windows身份验证,但后来不得不将其更改为匿名,我正确配置了CORS,但在launchSettings.json中的此设置是元凶,感谢您发布此信息!
HaRoLD

2

我使用的是.Net CORE 3.1,当我意识到我的代码已经开始实际工作但调试环境坏了时,我花了很长时间才把这头撞墙。因此,这里有2条提示,提示您是否要对问题:

  1. 如果您尝试使用ASP.NET中间件记录响应标头,则即使存在,“ Access-Control-Allow-Origin”标头也将永远不会显示。我不知道如何,但是它似乎是在管道之外添加的(最后我不得不使用wireshark来查看它)。

  2. 除非您的请求中包含“ Origin”标头,否则.NET CORE不会在响应中发送“ Access-Control-Allow-Origin”。邮递员不会自动设置此项,因此您需要自己添加。


1

.NET Core 3.1

为我工作,文档如何做到:

在启动类中:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 

在ConfigureServices()方法中:

    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com");
        });
    });

在Configure()方法中:

    app.UseCors(MyAllowSpecificOrigins);  

https://docs.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-3.1



0

我可以使用上面的MindingData的答案来工作,但必须使用Microsoft.AspNet.Cors而不是Microsoft.AspNetCore.Cors。我正在Visual Studio 2019中使用.NetCore Web应用程序API项目


2
注意:您不应该在ASP.Net Cor应用程序中使用Microsoft.AspNet.Cors。如果您使用的是.Net Core 3.0或更高版本,则完全不需要为CORS导入任何NuGet程序包。如果您使用的是.Net Core 2.3或更低版本,则需要NuGet的相应版本的Microsoft.AspNet.Cors。
FoggyDay

0

Microsoft.AspNetCore.Cors

将允许您使用内置功能执行CORS,但不能处理OPTIONS请求。到目前为止,最好的解决方法是按照上一篇文章中的建议创建一个新的中间件。检查以下帖子中标记为正确的答案:

在.NET Core Web API上为CORS启用OPTIONS标头


0

简便的方法。

  1. 安装套件

Install-Package Microsoft.AspNetCore.Cors

  1. 将下面的代码放在startup.cs文件中

app.UseCors(options => options.AllowAnyOrigin());


0

这是我的代码:)

  app.Use((ctx, next) =>
        {
            ctx.Response.Headers.Add("Access-Control-Allow-Origin", ctx.Request.Headers["Origin"]);
            ctx.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            ctx.Response.Headers.Add("Access-Control-Allow-Headers", "AccessToken,Content-Type");
            ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
            if (ctx.Request.Method.ToLower() == "options")
            {
                ctx.Response.StatusCode = 204;

                return Task.CompletedTask;
            }
            return next();
        });

0

这是我的方法。

我看到,在一些答案,他们正在设置app.UserCors("xxxPloicy")和推杆[EnableCors("xxxPloicy")]控制器。您不需要两者都做。

步骤如下。

在ConfigureServices内的Startup.cs中,添加以下代码。

    services.AddCors(c=>c.AddPolicy("xxxPolicy",builder => {
        builder.AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    }));

如果要在整个项目中应用,请在Startup.cs的Configure方法中添加以下代码

app.UseCors("xxxPolicy");

要么

如果要将其添加到特定控制器,则添加启用cors代码,如下所示。

[EnableCors("xxxPolicy")]
[Route("api/[controller]")]
[ApiController]
public class TutorialController : ControllerBase {}

有关更多信息:请参阅此


0

使用自定义的动作/控制器属性来设置CORS标头。

例:

public class AllowMyRequestsAttribute : ControllerAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // check origin
        var origin = context.HttpContext.Request.Headers["origin"].FirstOrDefault();
        if (origin == someValidOrigin)
        {
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin);
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            // Add whatever CORS Headers you need.
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // empty
    }
}

然后在Web API Controller / Action上:

[ApiController]
[AllowMyRequests]
public class MyController : ApiController
{
    [HttpGet]
    public ActionResult<string> Get()
    {
        return "Hello World";
    }
}

0

仅在此处添加答案,如果您正在使用app.UseHttpsRedirection(),而您没有点击SSL端口,请考虑将其注释掉。


0

我使用的是blazor webassembly作为客户端,而使用asp.net Web api核心作为后端,并且也存在cors问题。

我找到了以下代码的解决方案:

我的ASP.Net核心Web api Startup.cs ConfigureServices和Configure方法的第一行如下所示:

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
   {
        builder.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader();
    }));

 //other code below...
}

和我的Configure方法:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCors(
        options =>   options.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader()
            );
 //other code below...
}

更改http://example.com您的客户域或IP地址


-1
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddJsonOptions(options => {
                    var resolver = options.SerializerSettings.ContractResolver;
                    if (resolver != null)
                        (resolver as DefaultContractResolver).NamingStrategy = null;
                });

            services.AddDbContext<PaymentDetailContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DevConnection"))); //Dependency Injection
            // options => options.UseSqlServer() Lamda Expression

            services.AddCors(options =>
            {
                options.AddPolicy(MyAllowSpecificOrigins,
                    builder =>
                    {
                        builder.WithOrigins("http://localhost:4200").AllowAnyHeader()
                                .AllowAnyMethod(); ;
                    });
            });

请编辑您的答案,以包含和解释您的代码以及它与其他答案的不同之处。这将使您的帖子更有用,并且更有可能被赞成:)
Das_Geek
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.