【问题标题】:ASP .NET Core use multiple CORS policiesASP .NET Core 使用多个 CORS 策略
【发布时间】:2017-10-14 14:24:30
【问题描述】:

我正在尝试设置 2 个 CORS 策略。一个作为 api 默认值,另一个在 Controllers 上使用,因为我需要它们。我想这样做的原因是因为我有一个端点,它接收一个带有电子邮件信息的对象并发送一封电子邮件(与我网页上的联系我框一起使用)并让它只接受来自我的域的请求。

我的startup.cs文件sn-p:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("Example",
                    builder => builder.WithOrigins("http://www.example.com"));
                options.AddPolicy("AllowAll",
                    builder => builder.AllowAnyOrigin());
            });

            services.AddMvc();
            //other configure stuff
        }


 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseCors(builder =>
        {
            builder.AllowAnyHeader();
            builder.AllowAnyMethod();
            builder.WithOrigins("AllowAll");
        });

        app.UseMvcWithDefaultRoute();
    }

我的emailcontroller.cs 文件:

using System.Threading.Tasks;
using MyAPI.Models;
using MyAPI.Services;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;

namespace MyAPI.Controllers
{
    [Produces("application/json")]
    [Route("api/Email")]
    [EnableCors("Example")]
    public class EmailController : Controller
    {
        private readonly IEmailSender _emailSender;

        public EmailController(IEmailSender emailSender)
        {
            _emailSender = emailSender;
        }

        [HttpPost]
        public async Task Post([FromBody] Email email)
        {
            await _emailSender.SendEmailAsync(email);
        }
    }

}

用于发送电子邮件的Javascript:

function sendEmail(email)
{
    var urlToApi = "http://<ipToApi>:5000/api";
    $.ajax({
            method: "POST",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(email),     
            url: urlToApi + "/email/",
            success: function(data) {  
                console.log(data);
                console.log('probably sent');
            },
            error: function(jqXHR, textStatus, errorThrown){
                console.log(textStatus);
                alert("There was like, an error doing that");
            }
        });
}

这是我试图从http://www.example.com发送的内容

XMLHttpRequest cannot load http://<ipToApi>:5000/api/email/. 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested
 resource. Origin 'http://www.example.com' is therefore not allowed access.

编辑

这行得通:

services.AddCors(options =>
            {
                options.AddPolicy("Example",
                    builder => builder.WithOrigins("http://www.example.com")
                                        .AllowAnyHeader()
                                        .AllowAnyMethod());
                options.AddPolicy("AllowAll",
                    builder => builder.AllowAnyOrigin()
                                        .AllowAnyHeader()
                                        .AllowAnyMethod());
            });

【问题讨论】:

  • 您将原点设置为“AllowAll”
  • @Mardoxx 我认为这只会设置默认值。如果我把所有这些都注释掉,我可以在我的所有控制器上使用 [EnableCors("mypolicy")] 吗?
  • 你应该使用app.UseCors("AllowAll");
  • 您也不允许任何方法/标题。 CORS 规范说,如果任何检查未通过,则不要设置任何标头(至少 ASPNET Core 是这样解释它的!)所以这就是为什么我相信你会得到通用的 ...-Allow-Origin not present 错误。如果您将AllowAnyHeaderAllowAnyMethod 添加到这两个策略中,它可能会按预期工作。
  • @Mardoxx 谢谢!如果您将其发布为答案,我会接受它

标签: javascript c# .net asp.net-core cors


【解决方案1】:

要设置默认 CORS 策略,请使用 app.UseCors(string policyName) 过载。

您的 CORS 请求将失败,因为您拒绝所有标头和方法。根据我的阅读,CORS 规范指出,如果任何检查失败,您根本不应该设置任何标题。请参阅实现 here,这很可能是您的客户端将收到标准 No 'Access-Control-Allow-Origin' header is present 错误的原因,因为根本没有添加 no 标头,即使 Origin 检查通过。

以下内容应按预期工作,您的 [EnableCors(...)] 装饰器应覆盖默认值!

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

    services.AddMvc();
    //other configure stuff
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseCors("AllowAll"); //Default

    app.UseMvcWithDefaultRoute();
}

您可能需要将.AllowCredentials() 添加到您的政策中,但我不确定。也许阅读here

【讨论】:

  • 我认为控制器级别 [EnableCors] 不会覆盖默认值。这似乎只工作,因为默认是允许所有。
  • 使用 app.UseCors("AllowAll"); 使用在 mvc cors 属性之前触发的中间件,并且不会被它们覆盖。我认为这个答案有点误导,因为是的,它只适用于一个接一个地应用 2 个 cors 策略,这最终帮助了我 - andrewlock.net/a-deep-dive-in-to-the-asp-net-core-cors-library
【解决方案2】:

配置方法

app.UseRouting();
app.UseCors("CorsApi");
app.UseAuthentication();

ConfigureServices 方法

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

【讨论】:

    猜你喜欢
    • 2020-05-22
    • 2020-11-02
    • 2020-10-25
    • 2021-02-14
    • 2020-04-06
    • 2022-12-17
    • 2019-07-01
    • 2021-07-31
    • 2019-05-25
    相关资源
    最近更新 更多