针对特定控制器的ASP.NET Core禁用CORS [英] ASP.NET Core Disable CORS for specific controllers

查看:354
本文介绍了针对特定控制器的ASP.NET Core禁用CORS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have different set of controllers in my application (let's say A and B). CORS for A controller needs to be enabled and disabled for B controllers. I have configured CORS via the policies in the following way:

ConfigureServices方法:

ConfigureServices method:

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属性

Set of A controllers has EnableCors attribute

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

CORS可以按预期方式(通过浏览器测试)用于A控制器组.但是,它也适用于B控制器!我什至试图显式地禁用带有DisableCors属性的CORS:

CORS works for set of A controller as expected (tested via the browser). However, it also does work for B controllers! I even tried to disable CORS with DisableCors attribute explicitly:

[DisableCors]
public class ControllerB1: Controller

但是,无论如何,都可以从UI请求ControllerB1控制器.

However, ControllerB1 controller can be requested from UI anyway.

浏览器中B1控制器的标题

Headers in browser for B1 contoller

请求

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?

Could you please advise how to disable CORS for specific controllers?

推荐答案

在您的示例中,设置WebHost时要注意两件事:

In your example, you've done two things of note in setting up the WebHost:

  1. 创建了一个名为AllowCors的自定义CORS策略.
  2. 将CORS中间件添加到了使用AllowCors作为其policyName的管道中.
  1. Created a custom CORS policy named AllowCors.
  2. Added the CORS middleware to the pipeline, which uses AllowCors as its policyName.

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

Here's a snippet of the Invoke function that gets called for the CORS middleware:

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标头.

In this snippet, _policy is null and _corsPolicyName is AllowCors. Because AllowCors is the name of a valid policy that was added using AddCors, this results in the CORS middleware applying the revelant CORS headers for all requests.

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

In your example, you've also used both [EnableCors(...)] and [DisableCors], which are MVC authorisation filters. By doing this, you're mostly just telling MVC to take care of CORS, which is independent of the CORS middleware you've added to the WebHost's pipeline.

这种MVC和CORS中间件的组合导致了您意想不到的结果.中间件正在通过[DisableCors]属性将CORS标头添加到您的请求(无论是否),CORS中间件不知道该MVC概念(过滤器)甚至存在.

This combination of MVC and CORS middleware is what is causing your unexpected results. The middleware is adding the CORS headers to your request regardless of whether or not you're asking it not to by using the [DisableCors] attribute - the CORS middleware has no idea that this MVC concept (a filter) even exists.

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

Based on this information, you can fix your issue in one of two ways:

  1. 将呼叫中的policyName参数从对UseCors的调用中删除.
  2. 删除本身的UseCors调用.
  1. Remove the policyName parameter from your call to UseCors.
  2. Remove the UseCors call itself.

如果使用传递给AddCors委托的CorsOptions上的AddDefaultPolicy进行了配置,则使用选项1的UseCors中间件将使用默认策略.

With option 1, the UseCors middleware will use the default policy, if it's been configured using AddDefaultPolicy on the CorsOptions passed into the AddCors delegate.

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

With option 2, the CORS middleware is simply excluded from the pipeline. This will also work in your example, because you've used [EnableCors(...)] where you need it. This also means that you don't need to use [DisableCors] at all - it'll default to not adding the CORS headers.

这提出了一个问题:什么时候 [DisableCors]有用?例如,考虑以下基本控制器:

This raises the question: When would [DisableCors] be useful? As an example, consider the following basic controller:

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

    public IActionResult Action2() =>
        ...
}

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

It's clear that in this example, both Action1 and Action2 will set the CORS headers. If you didn't want Action2 to set the headers, you could annotate it with [DisableCors].

这篇关于针对特定控制器的ASP.NET Core禁用CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆