针对特定控制器的ASP.NET Core禁用CORS

时间:2018-09-27 09:50:19

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

我的应用程序中有一组不同的控制器(假设A和B)。需要为B控制器启用和禁用A控制器的CORS。 我已通过以下方式通过策略配置了CORS:

ConfigureServices方法:

services.AddCors(
    options =>
    {
        options.AddPolicy(
            "AllowCors",
            builder =>
                {
                    builder.AllowAnyOrigin().WithMethods(
                        HttpMethod.Get.Method,
                        HttpMethod.Put.Method,
                        HttpMethod.Post.Method,
                        HttpMethod.Delete.Method).AllowAnyHeader().WithExposedHeaders("CustomHeader");
                });
    });
services.AddMvcCore()

配置方法

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

A控制器的集合具有EnableCors属性

[EnableCors("AllowCors")]
public class ControllerA1: Controller

CORS可以按预期的那样用于A控制器集(通过浏览器测试)。但是,它也适用于B控制器!我什至尝试使用DisableCors属性显式禁用CORS:

[DisableCors]
public class ControllerB1: Controller

但是,仍然可以从UI请求ControllerB1控制器。

浏览器中B1控制器的标题

请求

Provisional headers are shown
Origin: http://localhost:5000
Referer: http://localhost:5000/all
User-Agent: Mozilla/5.0 AppleWebKit Chrome/69 Safari/537

响应

Request URL: http://XX.XX.XX.XX/getall
Request Method: GET
Status Code: 200 OK
Remote Address: XX.XX.XX.XX:80
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: CustomCount        
Content-Type: application/xml; charset=utf-8
Server: Kestrel

请问您如何为特定控制器禁用CORS?

2 个答案:

答案 0 :(得分:3)

在您的示例中,您在设置WebHost时做了两件事:

  1. 创建了一个名为AllowCors的自定义CORS策略。
  2. 将CORS中间件添加到了使用AllowCors作为其policyName的管道中。

这是Invoke函数的一个片段,被CORS中间件调用:

public async Task Invoke(HttpContext context)
{
    if (context.Request.Headers.ContainsKey(CorsConstants.Origin))
    {
        var corsPolicy = _policy ?? await _corsPolicyProvider?.GetPolicyAsync(context, _corsPolicyName);
        if (corsPolicy != null)
        {
            var corsResult = _corsService.EvaluatePolicy(context, corsPolicy);
            _corsService.ApplyResult(corsResult, context.Response);

    ...

在此代码段中,_policynull,而_corsPolicyNameAllowCors。因为AllowCors是使用AddCors添加的有效策略的名称,所以这导致CORS中间件对所有请求应用了最新的CORS标头。

在您的示例中,您还同时使用了[EnableCors(...)][DisableCors],它们是MVC授权过滤器。通过这样做,您基本上只是在告诉MVC照顾CORS,这是您添加到WebHost管道中的CORS中间件的独立

这种MVC和CORS中间件的组合导致了您意外的结果。中间件正在通过使用[DisableCors]属性向您的请求不管添加CORS标头,无论您是否要求-CORS中间件都不知道这个MVC概念(一个过滤器)甚至存在。

根据此信息,您可以通过以下两种方式之一解决问题:

  1. 从对policyName的调用中删除UseCors参数。
  2. 删除UseCors本身。

如果使用选项1,则UseCors中间件将使用默认策略,前提是已使用AddDefaultPolicy上传递给CorsOptions委托的AddCors配置了中间件。

使用选项2,可将CORS中间件从管道中简单排除。这在您的示例中也将起作用,因为您在需要的地方使用了[EnableCors(...)]。这也意味着您根本不需要使用[DisableCors]-默认情况下将不添加CORS标头。

这引发了一个问题:何时 [DisableCors]有用?例如,考虑以下基本控制器:

[EnableCors("AllowCors")]
public class ExampleController : ControllerBase
{
    public IActionResult Action1() =>
        ...

    public IActionResult Action2() =>
        ...
}

很明显,在此示例中,Action1Action2都将设置CORS标头。如果您不是想要Action2设置标题,则可以使用[DisableCors]对其进行注释。

答案 1 :(得分:0)

app.userCors 的顺序很重要

//...
app.UseRouting();
app.UseCors("customPolicy");
app.UseEndpoints(...)
//...