ASP.NET Core 为特定控制器禁用 CORS
Posted
技术标签:
【中文标题】ASP.NET Core 为特定控制器禁用 CORS【英文标题】:ASP.NET Core Disable CORS for specific controllers 【发布时间】:2019-03-03 04:51:00 【问题描述】:我的应用程序中有不同的控制器集(比如说 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?
【问题讨论】:
你如何在同一台机器上测试这个? 在不同的机器上测试,UI是localhost,API部署在远程服务器上。我在问题中添加了请求/响应标头 【参考方案1】:在您的示例中,您在设置 WebHost 时做了两件事:
-
创建了一个名为
AllowCors
的自定义 CORS 策略。
向管道添加了 CORS 中间件,该管道使用 AllowCors
作为其 policyName
。
这是为 CORS 中间件调用的 Invoke
函数的 sn-p:
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);
...
在这个 sn-p 中,_policy
是 null
,_corsPolicyName
是 AllowCors
。因为AllowCors
是使用AddCors
添加的有效策略的名称,这会导致CORS 中间件为所有请求应用相关的CORS 标头。
在您的示例中,您还使用了 [EnableCors(...)]
和 [DisableCors]
,它们是 MVC 授权过滤器。通过这样做,您主要是告诉 MVC 处理 CORS,它与您添加到 WebHost 管道的 CORS 中间件独立。
MVC 和 CORS 中间件的这种组合导致了您意想不到的结果。中间件将 CORS 标头添加到您的请求中不管您是否要求它不要使用 [DisableCors]
属性 - CORS 中间件不知道这个 MVC 概念(过滤器) 甚至存在。
根据此信息,您可以通过以下两种方式之一解决您的问题:
-
从您对
UseCors
的调用中删除policyName
参数。
删除 UseCors
调用本身。
如果使用选项 1,UseCors
中间件将使用默认策略,前提是它已在传递给 AddCors
委托的 CorsOptions
上使用 AddDefaultPolicy
进行配置。
使用选项 2,CORS 中间件简单地从管道中排除。这也适用于您的示例,因为您在需要的地方使用了[EnableCors(...)]
。这也意味着您根本不需要使用 [DisableCors]
- 它默认不添加 CORS 标头。
这就提出了一个问题:[DisableCors]
什么时候有用?例如,考虑以下基本控制器:
[EnableCors("AllowCors")]
public class ExampleController : ControllerBase
public IActionResult Action1() =>
...
public IActionResult Action2() =>
...
很明显,在此示例中,Action1
和 Action2
都将设置 CORS 标头。如果您不希望Action2
设置标题,您可以使用[DisableCors]
对其进行注释。
【讨论】:
【参考方案2】:app.useCors 的顺序很重要
//...
app.UseRouting();
app.UseCors("customPolicy");
app.UseEndpoints(...)
//...
【讨论】:
以上是关于ASP.NET Core 为特定控制器禁用 CORS的主要内容,如果未能解决你的问题,请参考以下文章
根据 ASP.NET Core 和 Entity Framework Core 中的条件禁用 [必需] 属性
从 ASP.NET CORE Web Api 获取 React 中的特定响应标头(例如,Content-Disposition)