5

Это будет дубликат How does Access-Control-Allow-Origin header work?, но метод там также не работает для меня. Я надеюсь, что я просто что-то упустил..NET Core UseCors() не добавляет заголовки

Я пытаюсь получить заголовок Access-Control-Allow-Origin в своем ответе от моего .NET Core Web API, к которому я обращаюсь через AJAX.

Я пробовал несколько вещей. Все, если не указано иное, были в файле Startup.cs.

Метод 1

Согласно Microsoft Documentation:

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add database 
    services.AddDbContext<DbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DbConnection"))); 

    // Add the ability to use the API with JSON 
    services.AddCors(); 

    // Add framework services. 
    services.AddMvc(); 
} 

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

    if (env.IsDevelopment()) 
    { 
     using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
     { 
      serviceScope.ServiceProvider.GetService<DbContext>().Database.Migrate(); 
      serviceScope.ServiceProvider.GetService<DbContext>().EnsureSeedData(); 
     } 
    } 

    app.UseCors(builder => builder.WithOrigins("https://localhost:44306").AllowAnyMethod()); 

    app.UseJwtBearerAuthentication(new JwtBearerOptions 
    { 
     Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"], 
     Audience = Configuration["Authentication:AzureAd:Audience"], 
    }); 

    app.UseMvc(); 
} 

Метод 2

public void ConfigureServices(IServiceCollection services) 
{ 
    // ... 

    services.AddCors(options => options.AddPolicy("AllowWebApp", 
     builder => builder.AllowAnyMethod() 
          .AllowAnyMethod() 
          .AllowAnyOrigin())); 
          //.WithOrigins("https://localhost:44306"))); 

    // ... 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    // ... 

    app.UseCors("AllowWebApp"); 

    // ... 
} 

Я также попытался добавить [EnableCors("AllowWebApp")] как на контроллер и метод.

От Почтальон, я получаю:

контент-кодирование → GZIP
типа содержимого → Текст/равнину; кодировка = UTF-8
датой → Ср, 25 января 2017 4:51:48 GMT
Сервер → Кестрела
статус → 200
изменяются → Accept-Encoding
х с питанием от-→ ASP.NET
x-sourcefiles → =? UTF-8? B? [REDACTED]

Я также пробовал его в Chrome и получил аналогичные заголовки.

Если это имеет значение, метод, который я пытаюсь получить, имеет атрибут Authorize. Но эта часть должна работать нормально (я, по крайней мере, получаю хороший ответ)

Итак, я пропустил что-то очень очевидное или это сломалось? В настоящее время я запускаю версию 1.1.0.


Edit добавления JS и контроллер Stub

function getContactPreviews(resultsCallback) { 
    var xmlhttp = new XMLHttpRequest(); 

    xmlhttp.onreadystatechange =() => { 
     if (xmlhttp.readyState == XMLHttpRequest.DONE && xmlhttp.status == 200) { 
      resultsCallback(JSON.parse(xmlhttp.response)); 
     } 
    } 

    xmlhttp.open("GET", "https://localhost:44357/api/User/ContactsPreview", true); 
    xmlhttp.setRequestHeader("Authorization", "Bearer " + localStorage.getItem("AuthorizationToken")); 
    xmlhttp.send(); 
} 

Контроллер Заглушка

[Authorize] 
[Route("api/[controller]")] 
public class UserController : ApiController 
{ 
    [HttpGet(nameof(ContactsPreview))] 
    [EnableCors("AllowWebApp")] 
    public IEnumerable<Customer> ContactsPreview() 
    { 
     // ... 
    } 
} 
+0

Как вы попадаете на сервер с помощью Postman? Заголовок будет возвращен только для запроса OPTIONS – Rob

+0

@Rob. Это то, чего мне не хватало. Меньше на стороне почтмана (я тоже пробовал его в Chrome, и это использовал правильный метод), и тем более на стороне контроллера. У меня был '[HttpGet]' вместо '[HttpOptions]'. У меня было ощущение, что это будет что-то немым. – David

+0

@Rob, однако Chrome все еще не работает. Он получает ошибку 204. Почтальон прекрасно работает. Оба используют один и тот же токен. Кэш отключен в Chrome. – David

ответ

6

Проблема в том, что при использовании аутентификации однонаправленного (или я бы себе), это добавляет заголовок «Авторизация», и сервер будет работать только в том случае, если настройка разрешает этот заголовок.

Существует два способа решить эту проблему, а ниже только необходим код. Он идет в методе Configure() в Startup.cs в решении Web API.

Метод 1: Разрешить все заголовки

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

Метод 2: Разрешить специальных заголовков

app.UseCors(builder => builder.WithOrigins("https://localhost:44306") 
           .AllowAnyMethod() 
           .WithHeaders("authorization", "accept", "content-type", "origin")); 

Дополнительные заголовки, потому что, согласно документации:

Браузеры не полностью состоят nt в том, как они устанавливают заголовки Access-Control-Request-Headers. Если вы устанавливаете заголовки на что угодно, кроме «*», вы должны включать по крайней мере «accept», «content-type» и «origin», а также любые пользовательские заголовки, которые вы хотите поддержать.