CORS не работи в уеб API с OWIN удостоверяване

В моето приложение използвам уеб api с удостоверяване, базирано на токени с поддръжка на CORS, но при заявка на клиента за токена, възникна грешка поради CORS (Заявката за кръстосано начало е блокирана: Политиката за същия произход забранява четенето на отдалечения ресурс на (моя сайт) име). Това може да бъде коригирано чрез преместване на ресурса в същия домейн или активиране на CORS.)

Бях конфигурирал всичко необходимо за поддръжка на CORS (мисля така). ето моята конфигурация

Owin начален клас

   public class Startup
    {
        public void Configuration(IAppBuilder app)
        {


            var config = new HttpConfiguration
            {
                DependencyResolver = new StructureMapWebApiDependencyResolver(container)

            };


            WebApiConfig.Register(config);  // registering web api configuration
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);  // cors for owin token pipeline
            app.UseWebApi(config);
            ConfigureOAuth(app);


        }

        public void ConfigureOAuth(IAppBuilder app)
        {
            var oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions()
            {

                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorizationServerProvider()
            };
            // Token Generation
            app.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

        }
    }

И моята конфигурация на webapi

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors();  // Corse support for Web api
            config.MapHttpAttributeRoutes(); // attribute based urls

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

        }
    }

тук конфигурация в web.config

<system.webserver>
 <httpProtocol>
      <customHeaders>
        <!-- Adding the following custom HttpHeader will help prevent CORS from stopping the Request-->
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
      </customHeaders>
    </httpProtocol>
</system.webserver>

и моята заглавка на заявката от mozilla

Accept  application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length  67
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
Host    talenterp
Origin  http://192.168.1.11:85
Referer http://192.168.1.11:85/
User-Agent  Mozilla/5.0 (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0

URL адресите на приложенията са

Сървърно приложение (което трябва да поддържа CORS)

{http://talenterp}

Крайна точка на токена:

{http://talenterp/token}

Клиентско приложение

{http://talentmvc:85}

NB: Вече добавих

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

в метода GrantResourceOwnerCredentials() на моя AuthorizationServerProvider


person Binson Eldhose    schedule 28.07.2014    source източник
comment
разрешен.. проблемът беше над конфигурацията CORS app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); config.EnableCors(); context.OwinContext.Response.Headers.Add(Access-Control-Allow-Origin, new[] { * }); току-що премахнах първия   -  person Binson Eldhose    schedule 28.07.2014
comment
здрасти Това наистина ли работи за вас? Благодаря.   -  person Rodrigo Longo    schedule 08.10.2014
comment
Вероятно е по-добре да премахнете реда config.EnableCors(), а не app.UserCors(). Първият не използва OWIN, вторият го прави. Занапред е по-добре да използвате настройките на тръбопровода OWIN.   -  person Echiban    schedule 16.07.2015
comment
@BinsonEldhose, моля, приемете отговор.   -  person Elger Mensonides    schedule 21.02.2016
comment
Трябва също да премахнете ‹customHeaders› от web.config, вижте stackoverflow.com/a/33664502/631527   -  person Toolkit    schedule 21.08.2018


Отговори (5)


Уверете се, че имате само

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

конфигуриран, а не също и стария стил 'config.EnableCors()' във вашия Global.asax или WebApiConfig. Освен това: поставете горното твърдение като първо във вашия собствен клас за стартиране. Да, това наистина има значение, настройването му по-късно също може да доведе до това, че Cors не работи.

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        ... etc
person Elger Mensonides    schedule 12.03.2015
comment
Как можем да персонализираме CORS в OWIN? като например, искам да разреша само този url: myapp.com - person fiberOptics; 03.03.2016
comment
@fiberOptics създайте CorsPolicy за това и добавете желаните от вас източници, създайте policyProvider и го добавете към обект CorsOptions - person Elger Mensonides; 03.03.2016
comment
Тази статия описва как да предоставите персонализирана политика на CORS: benfoster.io/blog/aspnet-webapi-cors - person Matze; 24.03.2016
comment
Това трябва да се отбележи като правилен отговор в днешно време. Благодаря ти! - person Jan Zahradník; 29.08.2016
comment
Преместихме извикването на UseCors на първото в метода за конфигурация и това реши нашия проблем 405. Postman работи добре, но беше 405 от Chrome. - person John Livermore; 18.04.2017
comment
Преместването на линията нагоре в горната част на метода за конфигурация поправи и моя. Благодаря! - person Craig; 25.08.2017
comment
place the above statement as the first one in your owin Startup class. .... 2 часа от живота ми бяха пропилени... - person Pogrindis; 27.04.2018
comment
@Pogrindis само два часа? Спомням си, когато за първи път се занимавах с WebApi, губех много повече време за това, което се оказа просто проблем с поръчка за регистрация на междинен софтуер. - person Ted; 15.02.2020
comment
@Ted Обзалагам се, че няма да загубите дори 10 минути, когато попаднете на него отново ;) - Не се притеснявайте обаче, имах неудобството да ровя в гугъл неща, да намирам резултати от SO и да разбера, че съм публикувал отговора.. Ние сме всички позволиха нашите старши моменти! - person Pogrindis; 15.02.2020
comment
И отново, и отново @Pogrindis. Някакъв stackenfreude, при който се наслаждавате на собственото си нещастие, докато ви връща към собствения ви отговор на stackoverflow, за който напълно сте забравили. Учудващо е колко често се случва това. - person Ted; 17.02.2020
comment
Това проработи за мен, заедно с това... stackoverflow.com/a/41988719/3284707 - person user3284707; 24.10.2020

OWIN и Microsoft.AspNet.WebApi.Cors са две отделни библиотеки и всяка от тях се нуждае от отделна конфигурация.

Деактивирайте използването на CORS с OWIN:

public void Configuration(IAppBuilder app)
{
        //app.UseCors(CorsOptions.AllowAll);

Намерете метода GrantResourceOwnerCredentials и добавете Access-Control-Allow-Origin към контекста, така че когато върне повикване след завършване на удостоверяването, браузърът намира заглавката и я приема.

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost" });

Сега инсталирайте пакета Microsoft.AspNet.WebApi.Cors от Nuget към вашия webapi проект и добавете това към метода за регистриране

public static void Register(HttpConfiguration config)
{
        var cors = new EnableCorsAttribute("http://localhost, ", "accept,accesstoken,authorization,cache-control,pragma,content-type,origin", "GET,PUT,POST,DELETE,TRACE,HEAD,OPTIONS");

        config.EnableCors(cors);

Това го направи за мен.

person Dado Kljuco    schedule 08.09.2016
comment
всъщност това работи за мен, за по-горната версия на owin това се получи. +1 - person Ehsan Zargar Ershadi; 09.02.2017
comment
Знам, че минаха почти 6 месеца, откакто публикувахте този отговор, но може би все още помните това. Интересува ме защо написахте http: //localhost, във var cors=new EnableCorsAttribute(http: //localhost, ... а просто не var cors=new EnableCorsAttribute(http: //localhost... ? I означава, че съм объркан с , (запетая и интервал) след http: //localhost - person David Maisuradze; 28.02.2017
comment
@Dato, това определено е остатък от списъка с домейни, които имах в моя код. EnableCorsAttribute ви позволява да подадете списък с домейни в един низ. Ето референтна връзка - person Dado Kljuco; 02.03.2017
comment
@DadoKljuco Благодаря за отговора. Странното е, че var cors=new EnableCorsAttribute(http: //localhost, ... работи добре, но var cors=new EnableCorsAttribute(http: //localhost... се проваля. И това беше причината, поради която бях объркан - person David Maisuradze; 07.03.2017

Особено ако имате проблем с маркера на носителя на Web API, когато използвате CORS, тогава не забравяйте да поставите „TOKEN“ в списъка с разрешените ви методи.

Моля, поставете кода във вашия system.webServer на web.config, така реших моя

<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE, TOKEN" />
 </customHeaders>
person Odeyinka Olubunmi    schedule 01.06.2015
comment
добавянето на TOKEN към стойностите реши проблема ми, докато всички други решения не работеха! - person Amir Oveisi; 22.08.2019

Имах същия проблем. В допълнение към горните указания (използвайки само app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll) и настройвайки го като първо нещо), трябваше да посоча следното във файла 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>

Поради някои заглавки, които изпращах в заявката за удостоверяване, заявка за опции се изпраща преди действителната заявка за POST и тя трябва да върне правилната заглавка „Access-Control-Allow-Origin“, преди да бъде изпратена POST.

Ако нито едно от CORS заглавките не бъде върнато от отговора на опциите, тогава POST няма да бъде изпратен изобщо. Добавената конфигурация позволява това поведение, както и за Trace.

Както е обяснено в тази публикация

person ven    schedule 18.08.2020
comment
За мен трябваше да се уверя, че премахнах OPTIONSVerbHandler, в противен случай решението на OWIN Cors не направи нищо (кодът се изпълнява, но нищо не се случва от него). - person Oblivion2000; 14.04.2021

Имах подобен проблем, опитах всички опции по-горе в startup.cs и добавих app.UseCors(CorsOptions.AllowAll); в горната част и в WebApiConfig деактивирах

public static void Register(HttpConfiguration config)
{
    //var cors = new EnableCorsAttribute("*", "*", "*");
    //config.EnableCors(cors);
}

а също и забранени кори в

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
}

И повтори това в обратен ред и също включи записи в web.config, но всички не проработиха.

Когато започнах да се питам защо app.UseWebApi(config); все още не е достъпен, видях някъде да работи. Огледах се и открих, че инсталирането на Install-Package Microsoft.AspNet.WebApi.OwinSelfHost го оправя.

В крайна сметка поправи целия проблем, въпреки че app.UseCors(CorsOptions.AllowAll) трябва да бъде поставен първо в метода startup.cs. Всъщност без app.UseWebApi(config), тествах в пощальон и крайните точки всъщност не съществуваха. Като цяло сега ми работи доста добре.

person Jude Opima    schedule 05.08.2020