Як зробити автентифікацію CORS у WebAPI 2?


74

Сценарій простий, мені потрібно увійти з іншого сервера (відмінного від сервера API), щоб отримати маркер доступу.

Я встановив Microsoft.Owin.Corsпакет на сервері API. У Startup.Auth.csфайлі під public void ConfigureAuth(IAppBuilder app)я додав

app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

У WebApiConfig.cs, під public static void Register(HttpConfiguration config), я додав у ці рядки:

// Cors
var cors = new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS");
config.EnableCors(cors);

Що ще мені змінити?


6
app.UseCors (CorsOptions.AllowAll) - дозволяє CORS для всіх запитів про перехресне походження на ваш сайт. config.EnableCors (..) дозволяє CORS лише для Web Api
Костянтин Таркус

Відповіді:


78

Подивіться, що я знайшов!

Додайте всередині спеціальні заголовки <system.webServer>.

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
  </customHeaders>
</httpProtocol>

Тоді я можу виконати автентифікацію CORS.


4
Я не уявляю, як би я зрозумів це без вашого повідомлення; Дякую! У документації веб-API не згадується про ці вимоги до конфігурації ... goo.gl/s9K6o2 & goo.gl/G8jKG0
TheFastCat

2
На жаль, як би люди не говорили цього робити, щось на шляху конвеєра автентифікації OWIN є 1) Перевизначення будь-якої відповіді, яку я вже писав через context.Request.Headers як частина проміжного програмного забезпечення OWIN 2) Навіть із налаштованими власними політиками, ігноруючи Корпуси OWIN для запиту "/ маркер". Принаймні для цілей тестування, я не впевнений, що зараз маю великий вибір.

1
Я думаю, що насправді має статися, нам слід обернути метод маркера в контролер облікового запису чимось, що називається входом, тоді стандартна конфігурація cors зробить цю роботу.
Тім Хонг,

7
Це не чудове рішення. Це працює, але це еквівалентно вимкненню брандмауера замість правильної настройки.
Piotr Stulinski

2
Я не погоджуюсь. CORS не є рішенням нічого. Брандмауер захищає клієнта, але CORS (неправильно) використовується як спосіб захисту сервера, але проста зміна клієнтом заголовків запитів, і ви золоті. Просто використовуйте, наприклад, прапор chrome --disable-web-security або шукайте розширення Allow-Control-Allow-Origin: * Chrome.
Peheje,

50

У мене було багато спроб і помилок, щоб встановити його для веб-клієнта на базі AngularJS.
Для мене наведені нижче підходи працюють із ASP.NET WebApi 2.2 та службою на основі OAuth.

  1. Встановіть Microsoft.AspNet.WebApi.Corsnuget-пакет.
  2. Встановіть Microsoft.Owin.Corsnuget-пакет.
  3. Додайте config.EnableCors(new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS, PUT, DELETE"));до верхньогоWebApiConfig.Register(config); рядка у файлі Startup.cs .
  4. Додайте app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);до файлу Startup.Auth.cs . Це потрібно зробити перед дзвінкомIAppBuilder.UseWebApi
  5. Видаліть усі налаштування xml, що робив Blaise.

Я знайшов багато варіантів і комбінацій налаштувань тут, у статті про stackoverflow або в блозі . Отже, підхід Блеза може бути неправильним, а може і не бути. Це просто інші налаштування, я думаю.


4
Це може створити таку проблему: aspnetwebstack.codeplex.com/workitem/1539
Мілен Ковачев

2
Я ввімкнув CORS у своїх конфігураціях OWIN та веб-API відповідно app.UseCorsта config.EnableCorsметодами, але, схоже, /tokenкінцева точка OWIN обробляється спеціально і не надсилає у відповідь заголовок HTTP Access-Control-Allow-Origin. Це вірно навіть при впровадженні рішення спеціальної політики Костянтином Таркусом нижче.

1
Вам потрібен пакет Nuget "Microsoft.AspNet.WebApi.Cors", щоб мати класи та метод для кроку 1.
Ян Захрадник,

3
Я повинен був встановити , Microsoft.Owin.Corsа також
Галдіна

33

Після багатьох годин пошуку та розгляду багатьох різноманітних рішень цього мені вдалося змусити це працювати згідно з наведеним нижче.

Існує низка причин, чому це відбувається. Швидше за все, ви ввімкнули CORS не в тому місці, або він увімкнений двічі, або взагалі не використовується.

Якщо ви використовуєте веб-API та кінцеву точку Owin Token, вам потрібно видалити всі посилання на CORS у вашому методі веб-API та додати правильний метод Owin, оскільки веб-додатки не працюватимуть із кінцевою точкою Token, тоді як Owin-корди працюватимуть як для Web Кінцеві точки API та Token auth, тому давайте почнемо:

  1. Переконайтеся, що у вас встановлений пакет Owin Cors Видаліть будь-який рядок, який у вас є, наприклад .config.EnableCors (); з вашого файлу WebAPIconfig.cs

  2. Перейдіть до файлу startup.cs і переконайтеся, що ви виконали Owin Cors перед запуском будь-якої іншої конфігурації.

    app.UseCors (Microsoft.Owin.Cors.CorsOptions.AllowAll); ConfigureAuth (додаток);

  3. Якщо у вас все ще виникають проблеми, перейдіть до: Startup.Auth.cs і переконайтеся, що у вашому методі ConfigureAuth є таке (вам не потрібно це робити, якщо файл startup.cs правильний)

app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);


2
Дякую @Piotr, це справжня робоча відповідь. Чи може Блез позначити це як справжню відповідь? з усіма іншими відповідями, OWIN / Token АБО WebAPI працює, поки вони не можуть працювати разом. У моєму випадку додавання XML у Web.config плюс config.EnableCors (...) призводить до додавання дубльованого заголовка [Access-Control-Allow-Headers], що заборонено в Chrome.
Джо Лау

Я теж зіткнувся з проблемою дублікатів заголовків після включення в проект як OWIN, так і веб-інтерфейсів API. Але, як зазначив у відповіді @Piotr, достатньо лише OWIN CORS, щоб подбати про це.
Dipendu Paul,

1
Це найкраща відповідь Щиро дякую. Крім того, вам може знадобитися пакет Microsoft.AspNet.WebApi.OwinSelfHost та пакет Microsoft.Owin.Cors для використання функції UseCors функції IAppBuilder (додаток)
janaka aravinda 02.03.18

21

web.config

<appSettings>
  <add key="cors:Origins" value="*" />
  <add key="cors:Headers" value="*" />
  <add key="cors:Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
</appSettings>

Startup.cs

var appSettings = WebConfigurationManager.AppSettings;

// If CORS settings are present in Web.config
if (!string.IsNullOrWhiteSpace(appSettings["cors:Origins"]))
{
    // Load CORS settings from Web.config
    var corsPolicy = new EnableCorsAttribute(
        appSettings["cors:Origins"],
        appSettings["cors:Headers"],
        appSettings["cors:Methods"]);

    // Enable CORS for ASP.NET Identity
    app.UseCors(new CorsOptions
    {
        PolicyProvider = new CorsPolicyProvider
        {
            PolicyResolver = request =>
                request.Path.Value == "/token" ?
                corsPolicy.GetCorsPolicyAsync(null, CancellationToken.None) :
                Task.FromResult<CorsPolicy>(null)
        }
    });

    // Enable CORS for Web API
    config.EnableCors(corsPolicy);
}

Примітка : app.UserCors(...)слід викликати перед налаштуванням ідентифікації ASP.NET.

Джерело: ASP.NET Web Application Starter Kit (ASP.NET Web API, Identity, SignalR)


Я реалізував це, і з подивом виявив, що, перевіряючи, чи виконується код політики у відладчику, у заголовку Access-Control-Allow-Origin у відповіді HTTP для запиту "/ token" немає заголовка.

Дивно, але після ввімкнення CORS за допомогою web.config, додавши заголовок відповіді вручну, а не через будь-яку конфігурацію CORS OWIN або Web API, потім видаливши це та повторно ввімкнувши мої конфігурації API, проблема з "/ token" пішла. Не впевнений у тому, що відбувається, але питання зараз зникло.

1
Майте на увазі, що порядок розміщення .EnableCors()вашого трубопроводу OWIN має значення. Ви хочете поставити його перед іншими матеріалами проміжного програмного забезпечення OWIN.
Костянтин Таркус

це web.config для веб-сайту api або для веб-сайту клієнта?
Мануель Ернандес,

@KonstantinTarkus Привіт, я хочу дозволити запити http лише з певної URL-адреси. що я повинен поставити замість значення в <add key = "cors: Origins" value = "*" />. Єдиною URL-адресою, яка може зробити запит, є localhost: 777. ?
Олексій

15

Щоб детальніше відповісти на відповідь Янджа, існує чудовий підручник з налаштування OWIN за допомогою веб-API та включення CORS у процесі за адресою http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web- api-2-owin-asp-net-identity /

Ви захочете додати пакет NuGet для CORS за допомогою команди:
Install-Package Microsoft.Owin.Cors -Version 2.1.0

Потім додайте
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

до вашого методу конфігурації в Startup.cs, щоб він виглядав приблизно так:


8
Для мене це не працює. І я думаю, що початкове питання стосувалося саме цього, чому app.UseCors (Microsoft.Owin.Cors.CorsOptions.AllowAll); не працює.
Мілен Ковачев

Я ввімкнув CORS у своїх конфігураціях OWIN та веб-API відповідно app.UseCorsта config.EnableCorsметодами, але, схоже, /tokenкінцева точка OWIN обробляється спеціально і не надсилає у відповідь заголовок HTTP Access-Control-Allow-Origin. Це вірно навіть при впровадженні рішення спеціальної політики Костянтином Таркусом нижче.

9

Відповідь для мене знайдено за адресою

Запит CORS перед вильотом Web Api 2 на токен на пред'явника

Зокрема, запит / Token із використанням реалізації OAuthAuthorizationServerProvider.GrantResourceOwnerCredentials знову додавав заголовок. Додайте матеріали OWIN CORS перед будь-якою іншою конфігурацією OWIN і видаліть заголовок із GrantResourceOwnerCredentials відповідно до цього посилання та voila. Удачі.


Ти врятував цілий мій день.
Суміт

9

Я просто хочу поділитися своїм досвідом. Я витратив половину дня, стукаючи головою і намагаючись змусити це працювати. Я прочитав численні статті та SO-запитання, і врешті-решт зрозумів, що сталося.

Лінія

app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

не був першим у Startupкласі Configurationметодом. Коли я перемістив його на вершину - все почало працювати чарівно.

І ніякі призначені для користувача заголовки в web.configабо config.EnableCors(corsPolicy);або що - або ще не було необхідності.

Сподіваюся, це допоможе комусь заощадити трохи часу.


1
врятував мене 30 хв до мого призначення :) спасибі! #magic lol
Норман Бентлі

Навіть якщо я додаю це як 1-й рядок у методі конфігурації класу запуску, я отримую помилку. Але коли я додаю конфігурацію разом з цим рядком, він починає видавати проблему з дублікатами.
bomaboom

4

Тут ви знайдете кілька способів увімкнення CORS у різних сферах: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

У будь-якому випадку у мене була та сама проблема, і, додаючи заголовки різними способами, я не отримав повного рішення.

Я з’ясував, що IIS використовує обробники, які замінюють конфігурацію веб-програми CORS, якщо ви не вказали протилежне.

У моєму випадку мені також довелося видалити використання обробників IIS, додавши таку конфігурацію в основну Web.config моєї програми:

<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

Майте на увазі, що ця конфігурація може бути встановлена ​​за замовчуванням під час створення нового проекту в залежності від його типу, але якщо ви починаєте з нуля, вам, ймовірно, доведеться додати цю конфігурацію.


Так! Це так сильно мене хвилює, використовуючи JSONP, поки я розробляю. Почав з нуля, як ти кажеш.
tigerswithguitars

2

Додавання заголовків клієнтів може не дати вам стільки свободи в налаштуванні своїх потреб безпеки. Це відкриває для світу всю іншу частину API. Наступний код робить це лише для "токена", а контролер іншої частини api повинен виконуватися за допомогою анотації EableCors.

Щоб увімкнути Cors, дотримуйтесь інструкцій тут .


1

При використанні проміжного програмного забезпечення OWIN для обробки CORS нам не потрібно додавати заголовки у файл WebAPIConfig або файл web.config. Так, додавання заголовків у файл web.config спрацьовує, коли вам потрібен загальнодоступний доступ, але якщо вам потрібно обмежити доступ на основі білого списку (доменів), то дозволити весь доступ більше не те, що ви хотіли б зробити.

За допомогою OWINS ми можемо впоратися з цим, реалізувавши цей обробник:

За допомогою цього обробника ми можемо виявити метод запиту (OPTIONS, POST ...) і якщо запит слід розглядати як кінцеву точку авторизації або маркера. У цій області можна додати логіку для перевірки заголовка (запиту) Origin та перевірки, чи слід дозволити цей домен, додавши заголовок відповіді Access-Control-Allow-Origin.

Докладніше про це дивіться за цим посиланням: http://www.ozkary.com/2016/04/web-api-owin-cors-handling-no-access.html


0

Повне рішення. Вам просто потрібно змінити деякі файли, це працює для мене.

Global.ascx

WebApiConfig.cs

Весь запит має виклик цього коду.

public static class WebApiConfig {
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
        AddRoutes(config);
    }

    private static void AddRoutes(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "Default",
            routeTemplate: "api/{controller}/"
        );
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute(
            origins: "*", 
            headers: "*", 
            methods: "*");
        config.EnableCors(cors);
    } }

Якийсь контролер

Нічого змінити.

Web.config

Вам потрібно додати обробники у вас web.config

<configuration> 
  <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>   
  </system.webServer> 
</configuration>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.