如何在 ASP.NET Core 中启用 CORS

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 中启用 CORS【英文标题】:How to enable CORS in ASP.NET Core 【发布时间】:2015-11-03 16:39:57 【问题描述】:

我正在尝试在我的 ASP.NET Core Web API 上启用跨源资源共享,但我卡住了。

EnableCors 属性接受 policyName 类型的 string 作为参数:

// Summary:
//     Creates a new instance of the Microsoft.AspNetCore.Cors.Core.EnableCorsAttribute.
//
// Parameters:
//   policyName:
//     The name of the policy to be applied.
public EnableCorsAttribute(string policyName);

policyName 是什么意思?如何在 ASP.NET Core Web API 上配置 CORS

【问题讨论】:

这里是文章docs.microsoft.com/en-us/aspnet/core/security/cors 【参考方案1】:

注意最后的“/” - 将阻止 CORS 来源

builder.WithOrigins("http://example.com/","http://localhost:55233/");

会阻止

使用

builder.WithOrigins("http://example.com","http://localhost:55233"); 

【讨论】:

【参考方案2】:

对于 ASP.NET Core 6:

var  MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>

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

// services.AddResponseCaching();

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

有关更多示例,请参阅 official docs。

对于 ASP.NET Core 3.1 和 5.0:

您必须在应用程序启动时在 ConfigureServices 方法中配置 CORS 策略:

public void ConfigureServices(IServiceCollection services)

    services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
    
        builder.WithOrigins("http://example.com")
               .AllowAnyMethod()
               .AllowAnyHeader();
    ));

    // ...

builder 中的 CorsPolicyBuilder 允许您根据需要配置策略。您现在可以使用此名称将策略应用于控制器和操作:

[EnableCors("MyPolicy")]

或将其应用于每个请求:

public void Configure(IApplicationBuilder app)

    app.UseCors("MyPolicy");

    // ...

    // This should always be called last to ensure that
    // middleware is registered in the correct order.
    app.UseMvc();

【讨论】:

我发现 app.UseCors("MyPolicy") 不适用于我的 API 端点。我需要在有问题的控制器端点上明确地 [EnableCors("MyPolicy")]。 来自the official docs:“要为整个应用程序启用CORS,请使用UseCors 扩展方法将CORS 中间件添加到您的请求管道中。请注意,CORS 中间件必须位于应用程序中任何已定义的端点之前您希望支持跨域请求(例如,在调用 UseMvc 之前)。” 我在 app.AddMvc() 之后添加了 app.UseCors() ,但它不起作用。因为使用方法的顺序会影响中间件的工作方式! 允许任何来源有风险吗? 这个答案对我不起作用,因为缺少 Microsoft.AspNetCore.Cors nuget 包。【参考方案3】:

这涵盖了每个端点。如果您想阻止某个端点,请使用此注释 [DisableCors] 它在这里很好地描述了。 https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0

    app.authentication()app.routing()之间添加app.usecors(policyName)如果你在上面使用app.usMvc()。在Configure方法里面。

    configureService方法内部

services.AddCors(options => options.AddPolicy(name: mypolicy,     builder =>      builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin(); ));
    在每个控制器中添加[EnableCors("mypolicy")]
        [EnableCors("mypolicy")] 
        [Route("api/[controller]")] [ApiController] 
        public class MyController : ControllerBase


例如:-

  namespace CompanyApi2
        
            public class Startup
            
                public Startup(IConfiguration configuration)
                
                    Configuration = configuration;
                
        
                public IConfiguration Configuration  get; 
        
                // This method gets called by the runtime. Use this //method to add services to the container.
                public void ConfigureServices(IServiceCollection services)
                
                    services.AddCors(options =>
                        options.AddPolicy(name: mypolicy,
                            builder =>
                            
                                builder.AllowAnyHeader().AllowAnyMethod()
                                    .AllowAnyOrigin();
                            )); //add this
                    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                    services.AddScoped<IDatarepository, DatabaseRepository>();
                
        
                public string mypolicy = "mypolicy";
        
                // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
                public void Configure(IApplicationBuilder app, IHostingEnvironment env)
                
                    if (env.IsDevelopment())
                    
                        app.UseDeveloperExceptionPage();
                    
                    else
                    
                        app.UseHsts();
                    
        
                    app.UseCors(mypolicy); //add this
                    app.UseHttpsRedirection();
                    app.UseMvc();
                
            
        

【讨论】:

【参考方案4】:

适用于 .NET Core 1 和 .Net Core 2

如果使用.Net-Core 1.1

不幸的是,在这种特定情况下,文档非常混乱。所以我会让它变得非常简单:

Microsoft.AspNetCore.Cors nuget 包添加到您的项目中

ConfigureServices方法中,添加services.AddCors();

Configure方法中,在调用app.UseMvc()app.UseStaticFiles()之前,添加:

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

就是这样。每个客户端都可以访问您的 ASP.NET Core 网站/API。


如果使用.Net-Core 2.0

Microsoft.AspNetCore.Cors nuget 包添加到您的项目中

ConfigureServices方法中,调用services.AddMvc()之前,添加:

  services.AddCors(options =>
     
         options.AddPolicy("AllowAll",
             builder =>
             
                 builder
                 .AllowAnyOrigin() 
                 .AllowAnyMethod()
                 .AllowAnyHeader()
                 .AllowCredentials();
             );
     );

(重要)Configure方法中,调用app.UseMvc()之前,添加app.UseCors("AllowAll");

"AllowAll" 是我们需要在app.UseCors 中提及的策略名称。它可以是任何名称。

【讨论】:

是的,我以为我只能启用其中一个! 谢谢。在 UseMvc 之后我有我的 AddCors,这导致它无法正常工作。你的答案是唯一提到这一点的答案。 这行不通我不认为。提供凭据时,您不能允许任何来源。我仍在努力让它发挥作用。 这是关键部分:.UseCors().UseMvc() 之前 在 UserMvc 之前不了解 UseCors 浪费了时间......感谢您的帮助!【参考方案5】:

如下所示与 .NET Core 3.1 一起使用

    确保将UseCors 代码放在app.UseRouting();app.UseAuthentication(); 之间
app.UseHttpsRedirection();

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

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints => 
    endpoints.MapControllers();
);
    然后将此代码放入ConfigureServices方法中
services.AddCors(options =>

    options.AddPolicy("CorsApi",
        builder => builder.WithOrigins("http://localhost:4200", "http://mywebsite.com")
            .AllowAnyHeader()
            .AllowAnyMethod());
);
    我把它放在了基本控制器的上方
[EnableCors("CorsApi")]
[Route("api/[controller]")]
[ApiController]
public class BaseController : ControllerBase

现在我所有的控制器都将继承 BaseController 并启用 CORS

【讨论】:

直到我 place the UseCors code between app.UseRouting(); and app.UseAuthentication(); 没有人提到除了@tfa UseCors 代码的位置必须在 app.UseRouting();和 app.UseAuthentication();有关系! CORS 对我不起作用,直到我知道调用顺序很重要。谢谢! ? 使用默认策略是否还需要添加属性?仅供参考,我已在 [EnableCors] 和 .Net 5 中进行了测试。 @0014 - 非常感谢,你是唯一一个帮助我完成这项工作的人。这些必需的 order 方法调用似乎是非常糟糕的设计。我理解他们为什么会这样工作,但该死的太糟糕了。【参考方案6】:

.Net CORE 3.1 使用:

app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader())

【讨论】:

【参考方案7】:

安装nuget包Microsoft.AspNetCore.CORS

Startup.csConfigureServices方法下的services.AddMVC()前添加如下代码

services.AddCors(options =>

    options.AddPolicy("AllowMyOrigin", p =>
    
        p.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod();
    );
);

Startup.cs 中的Configure 方法中,在调用app.UseMvc() 之前添加app.UseCors("AllowMyOrigin");

请注意,当从客户端发送请求时,请记住使用 https 而不是 http。

【讨论】:

【参考方案8】:

如下所示与 .Net Core 3.1 一起使用:

ConfigureServices() 方法中:

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

Configure()方法中:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  
   ...
   app.UseCors(builder =>
          builder.AllowAnyOrigin()
          .AllowAnyHeader()
          .AllowAnyMethod()
        );
   ...
  

【讨论】:

【参考方案9】:

最近在 azure web 应用上托管 web 应用服务器时,不得不编辑 azure app cors 设置来解决问题(仅代码没有解决问题)

    安全性较低 - 启用 Access-Control-Allow-Credentials - 将其留空并添加 * 作为允许的来源 标记 Enable Access-Control-Allow-Credentials,然后添加您希望允许来自的请求的域

【讨论】:

【参考方案10】:

在我设法在最琐碎的 CORS 问题上浪费了两个小时之后,一些故障排除技巧:

    如果您看到 CORS policy execution failed 已登录...不要假设您的 CORS 策略未正确执行。事实上,CORS 中间件可以正常工作,并且您的策略正在正确执行。这个措辞糟糕的消息的唯一含义是请求的来源与任何允许的来源 (see source) 不匹配,即请求被禁止。

    原点检查(从 ASP.NET Core 5.0 开始)以一种非常简单的方式发生......即在您通过 WithOrigins() 提供的字符串与 @ 中存在的字符串之间进行区分大小写的序号字符串比较 (see source) 987654325@.

    如果您使用尾部斜杠 / 设置允许的原点,或者如果它包含大写字母,CORS 可能会失败。 (在我的例子中,我确实不小心复制了带有斜杠的主机。)

【讨论】:

【参考方案11】:
public void ConfigureServices(IServiceCollection services)

    services.AddCors(options =>
    
        options.AddPolicy("AllowAnyOrigin",
            builder => builder
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader());
    );

    services.Configure<MvcOptions>(options => 
        options.Filters.Add(new CorsAuthorizationFilterFactory("AllowAnyOrigin"));
    );            

【讨论】:

绕过已经部署的浏览器安全性的绝妙方法。只是不要! 我认为这不应该被否决。这是一种“替代”方式。您可以使用“UseCors()”方法,也可以像 Nathan 在这里所做的那样添加一个全局 MVC 过滤器。 这适用于我在 .net core 2.2 上加上 app.UseCors("AllowAnyOrigin");在“配置”方法中 “将 Microsoft.AspNetCore.Cors nuget 包添加到您的项目”很重要。谢谢你的提及!【参考方案12】:

如果您收到错误消息“请求的资源上不存在 'Access-Control-Allow-Origin' 标头。”特别是对于 PUTDELETE 请求,您可以尝试在 IIS 上禁用 WebDAV。

显然,WebDAVModule 默认启用,默认禁用 PUT 和 DELETE 请求。

要禁用 WebDAVModule,请将其添加到您的 web.config:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
    <remove name="WebDAVModule" />
  </modules>
</system.webServer>

【讨论】:

【参考方案13】:

您可以通过三种方式启用 CORS:

中间件中使用命名策略或默认策略。 使用端点路由。 带有 [EnableCors] 属性。

使用命名策略启用 CORS:

public class Startup

    readonly string CorsPolicy = "_corsPolicy";

    public void ConfigureServices(IServiceCollection services)
    
        services.AddCors(options =>
        
            options.AddPolicy(name: CorsPolicy,
                              builder =>
                              
                                 builder.AllowAnyOrigin()
                                      .AllowAnyMethod()
                                      .AllowAnyHeader()
                                      .AllowCredentials();
                              );
        );

        // services.AddResponseCaching();
        services.AddControllers();
    

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        app.UseRouting();

        app.UseCors(CorsPolicy);

        // app.UseResponseCaching();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllers();
        );
    

使用 UseResponseCaching 时,必须在 UseResponseCaching 之前调用

UseCors

使用默认策略启用 CORS:

public class Startup

    public void ConfigureServices(IServiceCollection services)
    
        services.AddCors(options =>
        
            options.AddDefaultPolicy(
                builder =>
                
                     builder.AllowAnyOrigin()
                                      .AllowAnyMethod()
                                      .AllowAnyHeader()
                                      .AllowCredentials();
                );
        );

        services.AddControllers();
    

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllers();
        );
    

通过端点启用 CORS

public class Startup

    readonly string CorsPolicy = "_corsPolicy ";

    public void ConfigureServices(IServiceCollection services)
    
        services.AddCors(options =>
        
            options.AddPolicy(name: CorsPolicy,
                              builder =>
                              
                                  builder.AllowAnyOrigin()
                                      .AllowAnyMethod()
                                      .AllowAnyHeader()
                                      .AllowCredentials();
                              );
        );

        services.AddControllers();
    

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        app.UseRouting();

        app.UseCors();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllers()
                     .RequireCors(CorsPolicy)
        );
    

使用属性启用 CORS

你有两个选项

[EnableCors] 指定默认策略。 [EnableCors("Policy String")] 指定命名策略。

【讨论】:

不编译就无法配置 CORS,这很糟糕。如果您的客户更改其地址,您必须经历重建过程和重新部署。 MS 并没有想太多。【参考方案14】:

第 1 步:我们的项目中需要 Microsoft.AspNetCore.Cors 包。要安装,请转到工具 -> NuGet 包管理器 -> 管理 NuGet 包以获取解决方案。搜索 Microsoft.AspNetCore.Cors 并安装包。

第 2 步:我们需要将 CORS 注入到容器中,以便应用程序可以使用它。在 Startup.cs 类中,我们去 ConfigureServices 方法注册 CORS。

因此,在我们的服务器应用程序中,让我们转到 Controllers -> HomeController.cs 并将 EnableCors 装饰器添加到 Index 方法(或您的特定控制器和操作):

更多详情Click Here

【讨论】:

嘿,shebin,您介意更新您博客的 URL,该 URL 看起来已损坏并将代码内联为文本而不是文本图片吗?【参考方案15】:

上面提到的所有解决方法可能有效,也可能无效,在大多数情况下都无效。我在这里给出了解决方案

Currently I am working on Angular and Web API(.net Core) and came across CORS issue explained below

上面提供的解决方案将始终有效。对于“OPTIONS”请求,确实有必要启用“匿名身份验证”。使用此处提到的解决方案,您不必执行上述所有步骤,例如 IIS 设置。

无论如何,有人将我上面的帖子标记为与这篇文章重复,但我可以看到这篇文章只是为了在 ASP.net Core 中启用 CORS,但我的帖子与在 ASP.net Core 中启用和实现 CORS 和角度。

【讨论】:

【参考方案16】:

特别是在带有 SignalR 的 dotnet core 2.2 中,您必须更改

.WithOrigins("http://localhost:3000")

.SetIsOriginAllowed(isOriginAllowed: _ =&gt; true) //for all origins

而不是.AllowAnyOrigin().AllowCredentials()

https://trailheadtechnology.com/breaking-change-in-aspnetcore-2-2-for-signalr-and-cors/

https://github.com/aspnet/AspNetCore/issues/4483

【讨论】:

在 .NET Core 控制台应用程序中使用 SignalR,这是我的场景中唯一可行的解​​决方案。【参考方案17】:

必须在 Startup.cs 类中配置

services.AddCors(options =>
        
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        );

【讨论】:

【参考方案18】:

如果你在 IIS 上托管,一个可能的原因是你得到这个是因为 IIS 阻止了 OPTIONS 动词。为此,我花了将近一个小时:

一个明显的迹象是您在OPTIONS 请求期间收到404 错误。

要解决此问题,您需要明确告诉 IIS 阻止 OPTIONS 请求。

转到请求过滤:

确保允许 OPTIONS:

或者,只需使用以下设置创建 web.config

<system.webServer>
    <security>
        <requestFiltering>
            <verbs>
                <remove verb="OPTIONS" />
                <add verb="OPTIONS" allowed="true" />
            </verbs>
        </requestFiltering>
    </security>
</system.webServer>

【讨论】:

非常感谢。我在docs.microsoft.com/en-us/aspnet/core/security/… 上尝试了所有方法,但我只收到 CORS 错误。直到有人指出你的答案......我想知道为什么 MS 的人不关心在他们的指南中包含这个小提示。【参考方案19】:

基于Henk's answer,我已经能够提出特定的域、我想要允许的方法以及我想要启用 CORS 的标头:

public void ConfigureServices(IServiceCollection services)

    services.AddCors(options =>
         options.AddPolicy("AllowSpecific", p => p.WithOrigins("http://localhost:1233")
                                                   .WithMethods("GET")
                                                   .WithHeaders("name")));
    services.AddMvc();

用法:

[EnableCors("AllowSpecific")]

【讨论】:

这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。 To critique or request clarification from an author 我不认为这里是这种情况,Henk 的答案已经被标记了。如果您想允许特定域,我的回答是附加组件。 您的代码中缺少某些内容,“IServiceCollection”不包含“ConfigureCors”的定义。请检查并尝试给出完整的答案。 @Sami-L 请检查我更新的答案。发现ConfigureCors改成了AddCors

以上是关于如何在 ASP.NET Core 中启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

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

在 ASP.Net 5 / Core 中启用跨域资源共享 (CORS)

如何在 asp.net core 3.1 中为每种类型的请求启用 Cors

在 asp.net core 中启用 CORS

在 ASP.Net Core 5 WebAPI 中启用 CORS

无法在 ASP.Net Core Web api 中启用 CORS