Подтвердить что ты не робот

ASP.NET Core CORS WebAPI: нет заголовка Access-Control-Allow-Origin

Я развернул свой веб-API ASP.NET Core для Azure, и я могу получить доступ к его конечным точкам с помощью Swagger или веб-отладчика, такого как Fiddler. В обоих случаях (то же самое происхождение в Swagger, различное происхождение с использованием Fiddler с моего компьютера), при доступе к API-интерфейсам я получаю ожидаемый результат, а CORS включен в моем Startup.cs:

  • добавить services.AddCors(); в ConfigureServices.

  • добавьте промежуточное ПО к Configure: я знаю, что здесь имеет значение порядок (ASP.NET 5: Access-Control-Allow-Origin в ответ), поэтому я помещаю этот вызов в начало метода, которому предшествуют только протоколирование или диагностическое промежуточное ПО; вот мой полный метод:


public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    ILoggerFactory loggerFactory,
    IDatabaseInitializer databaseInitializer)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
    loggerFactory.AddNLog();

    // to serve up index.html
    app.UseDefaultFiles();
    app.UseStaticFiles();

    // http://www.talkingdotnet.com/aspnet-core-diagnostics-middleware-error-handling/
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();

    // CORS
    // https://docs.asp.net/en/latest/security/cors.html
    app.UseCors(builder =>
            builder.WithOrigins("http://localhost:4200", "http://www.myclientserver.com")
                .AllowAnyHeader()
                .AllowAnyMethod());

    app.UseOAuthValidation();
    app.UseOpenIddict();
    app.UseMvc();

    databaseInitializer.Seed().GetAwaiter().GetResult();
    env.ConfigureNLog("nlog.config");

    // swagger
    app.UseSwagger();
    app.UseSwaggerUi();
}

localhost CORS используется во время разработки и относится к приложению Angular2 CLI. CORS работает нормально локально, а мои приложения для клиентов и API находятся на разных портах на одном и том же локальном хосте, поэтому это "истинное" кросс-происхождение (я замечаю это из-за предложений, которые я нашел здесь: https://weblog.west-wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas: автор сообщения отмечает, что заголовок CORS в ответе отправляется только тогда, когда это действительно необходимо, т.е. в истинных средах с перекрестным происхождением).

Используя Fiddler, я могу успешно получить доступ к удаленному API, но я получаю NO Access-Control-Allow-Origin. Таким образом, при вызове API из браузера (через мое клиентское приложение) запрос AJAX завершается с ошибкой, даже если сервер возвращает 200. Пример запроса Fiddler (успех):

GET http://mywebapisiteurl/api/values HTTP/1.1
User-Agent: Fiddler

Ответ:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=3d551180c72208c1d997584c2b6119cf44e3a55c868f05ffc9258d25a58e95b1;Path=/;Domain=prinapi.azurewebsites.net
Date: Thu, 01 Dec 2016 10:30:19 GMT

["value1","value2"]

При попытке доступа к удаленному API, развернутому на Azure, мое клиентское приложение всегда с ошибкой выполняет запрос AJAX:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.myclientserver.com' is therefore not allowed access.

Вот пример кода клиента с использованием Angular2 (с помощью Plunker):

import {Component, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import { Http, Headers, Response } from '@angular/http';
import { HttpModule } from '@angular/http';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <button (click)="test()">test</button>
    </div>
  `,
})
export class App {
  name:string;
  constructor(private _http: Http) {
    this.name = 'Angular2'
  }
  public test() {
    this._http.get('http://theapisiteurlhere/api/values',
    {
        headers: new Headers({
          'Content-Type': 'application/json'
        })
    })
    .subscribe(
      (data: any) => {
        console.log(data);
      },
      error => {
        console.log(error);
      });
  }
}

@NgModule({
  imports: [ BrowserModule, HttpModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

Подводя итог, кажется, что сервер API ASPNET не возвращает ожидаемые заголовки CORS, и поэтому мой клиент на базе браузера, размещенный на другом источнике, терпит неудачу. Тем не менее, установка CORS, похоже, в порядке, по крайней мере, судя по приведенной выше документации; Я нахожусь в подлинной среде кросс-происхождения; и я размещаю промежуточное ПО перед другими. Может быть, мне не хватает чего-то очевидного, но поиск по ним - вот все рекомендации, которые я нашел. Любой намек?

UPDATE

В ответ на @Daniel J.G: запрос/ответ от скрипача успешны:

GET http://theapiserver/api/values HTTP/1.1
User-Agent: Fiddler
Host: theapiserver
Origin: http://theappserver/apps/prin

и

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://theappserver/apps/prin
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=3d551180c72208c1d997584c2b6119cf44e3a55c868f05ffc9258d25a58e95b1;Path=/;Domain=theapiserver
Date: Thu, 01 Dec 2016 14:15:21 GMT
Content-Length: 19

["value1","value2"]

Запрос/ответ от Angular2 (Plunker) вместо этого завершается неудачно, как сообщается. Проверяя сетевой трафик, я вижу только запрос перед полетом:

OPTIONS http://theapiserver/api/values HTTP/1.1
Host: theapiserver
Proxy-Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://run.plnkr.co
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: http://run.plnkr.co/h17wYofXGFuTy2Oh/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6

HTTP/1.1 204 No Content
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=3d551180c72208c1d997584c2b6119cf44e3a55c868f05ffc9258d25a58e95b1;Path=/;Domain=theapiserver
Date: Thu, 01 Dec 2016 14:23:02 GMT

После этого запрос завершается с ошибкой и больше трафика не поступает на сервер. Сообщенная проблема заключается в том, что Response to preflight request doesn't pass access control check, опять же из-за отсутствия заголовка в ответе:

XMLHttpRequest cannot load http://theapiserver/api/values. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.plnkr.co' is therefore not allowed access.
4b9b3361

Ответ 1

Вот ответ на мой собственный вопрос, скопированный из комментариев: я не заметил, что на портале Azure есть раздел CORS. Если я не укажу здесь разрешенное происхождение, моя конфигурация на основе кода будет совершенно неактуальной. Это выглядит странно для меня, так как я вынужден дублировать URL-адреса здесь, но как только я добавил * к разрешенным источникам там, это сработало.

Ответ 2

Добавление метода .AllowAnyOrigin() может решить вашу проблему

    app.UseCors(builder =>
        builder.WithOrigins("http://localhost:4200", "http://www.myclientserver.com")
            .AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod());

Ответ 3

Добавление метода .AllowAnyHeader() может решить вашу проблему

app.UseCors(builder => builder.WithOrigins("http://localhost:4200")
                              .AllowAnyMethod()
                              .AllowAnyHeader());

Ответ 4

Сообщение об ошибке очень ошибочно. Я получал ту же ошибку после попытки добавить новую таблицу в DbContext. Angular выдавал ошибку "Access-Control-Allow-Origin", но почтальон выдавал 500 внутренних ошибок сервера. Сбой метода Login при попытке вызвать _userManager.FindByEmailAsync(). Надеюсь, это поможет кому-то еще.

Ответ 5

Проект WebApi --- > Щелкните правой кнопкой мыши ссылку "Ссылки" → "Поиск ядра" в разделе "Управление пакетами Nuget". Добавьте Microsoft.AspNet.WebApi.Cors к проекту, установив

Добавьте следующий код в файл WebApi.Config в папке App_Start в проекте.

var cors = new EnableCorsAttribute ( "," "," *"); config.EnableCors(CORS);

введите здесь описание изображения

введите здесь описание изображения