ASP.NET Core Отключить CORS для определенных контроллеров - PullRequest
0 голосов
/ 27 сентября 2018

У меня другой набор контроллеров в моем приложении (скажем, A и B).CORS для контроллера A должен быть включен и отключен для контроллеров B.Я настроил 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!Я даже пытался явно отключить CORS с атрибутом DisableCors:

[DisableCors]
public class ControllerB1: Controller

Тем не менее, контроллер 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 для определенных контроллеров?

1 Ответ

0 голосов
/ 27 сентября 2018

В вашем примере вы настроили две вещи при настройке WebHost:

  1. Создали пользовательскую политику CORS с именем AllowCors.
  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);

    ...

В этом фрагменте _policy равно null, а _corsPolicyName равно AllowCors.Поскольку AllowCors - это имя действительной политики, добавленной с использованием AddCors, это приводит к тому, что промежуточное программное обеспечение CORS применяет соответствующие заголовки CORS для всех запросов .

В вашем примереВы также использовали [EnableCors(...)] и [DisableCors], которые являются фильтрами авторизации MVC.Делая это, вы в основном просто говорите MVC позаботиться о CORS, который является независимым промежуточным ПО CORS, которое вы добавили в конвейер WebHost.

Эта комбинация MVC иПромежуточное программное обеспечение CORS - это то, что вызывает ваши неожиданные результаты.Промежуточное программное обеспечение добавляет заголовки CORS к вашему запросу независимо от того, или нет, с помощью атрибута [DisableCors] вы запрашиваете или нет - промежуточное программное обеспечение 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() =>
        ...
}

Понятно, что в этом примере и Action1, и Action2 будут устанавливать заголовки CORS.Если вы не не хотите Action2 установить заголовки, вы можете пометить его с помощью [DisableCors].

...