2016-09-21 14 views
6

Üç farklı SPA tarafından çağrılan bir ASP.NET web API vardır. Web API'sı için Windows kimlik doğrulaması kullanıyorum.ASP.NET Web API CORS nasıl çözülür? PUT ve DELETE isteklerini birden çok kaynak kullanarak kullanırken ön kontrol sorunu?

Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin (...) is therefore not allowed access. 

Ben Global.asax.cs aşağıdaki yöntemi ekleyerek çözüldü: Bu, bu uçuş öncesi konuyu neden

<httpProtocol> 
    <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="http://localhost:63342" /> 
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" /> 
     <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> 
     <add name="Access-Control-Allow-Credentials" value="true" /> 
    </customHeaders> 
</httpProtocol> 

: Başlangıçta böyle Web.config, CORS'yi yapılandırmak için çalıştı

protected void Application_BeginRequest() 
{ 
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") 
    { 
     Response.Flush(); 
    } 
} 

Bu yaklaşım tek bir SPA için mükemmel bir şekilde çalıştı.

<add name="Access-Control-Allow-Origin" value="http://localhost:63342,http://localhost:63347,http://localhost:63345/> 

ama görünüşe göre izin verilmez: Ben Web.config gidip bu gibi diğer kökenlerini eklemek düşündüm. Bu, aşağıdaki hata üretilen:

: Yani denemek ve bunu düzeltmek için, benim yaklaşım değişti ve bunun yerine böyle Kayıt yönteminde, WebAPIConfig.cs üzerinde CORS'yi yapılandırmak denemeye karar verdi
The 'Access-Control-Allow-Origin' header contains multiple values (...), but only one is allowed. Origin (...) is therefore not allowed access. 

var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "Origin, X-Requested-With, Content-Type, Accept", "GET, POST, PUT, DELETE"); 
cors.SupportsCredentials = true; 
config.EnableCors(cors); 

Bunun işe yarayacağını düşündüm ancak şimdi PUT ve DELETE isteklerini kullanırken ön far hatalarını tekrar ediyorum ve bunu nasıl düzeltebileceğimi bilmiyorum. Application_BeginRequest yönteminde hata ayıkladım ve hala OPTIONS isteğini temizliyorum, bu nedenle bu hatanın nedenine dair hiçbir fikrim yok. Bu sorunu nasıl çözebileceğimi bilen var mı?

DÜZENLEME:

uçuş öncesi hatasının baskı:

enter image description here

+0

: başkası sorun yaşamaya devam ederse, bana benim cevap ulaşmak yardımcı olan aşağıdaki yayınlar okuma tavsiye @Aravind Üzgünüm Sugg'la ilgili çözümü gerçekten anlayamıyorum Tahmin edeyim çünkü SO bazı sebeplerden alıntıları ikiye katlıyor. Bir şekilde başka bir şekilde yazabilir misiniz? –

+0

Tüm etki alanlarına ve yöntemlere 'new EnableCorsAttribute (" * "," * "," * ");' 'Bunu kullanmanın en iyi yolu, ICorsPolicyProvider kullanarak kendi özel özniteliğinizi oluşturmak ve GetCorsPolicyAsync yöntemini uygulamaktır. – Paresh

+0

@Paresh Ama kullanamıyorum * çünkü windows kimlik doğrulaması kullanıyorum ve uyumsuz. Ayrıca sadece bu üç URL'ye izin vermek istiyorum. –

cevap

7
ben daha böyle, Global.asax.cs içinde Application_BeginRequest yöntemini özelleştirerek benim sorunu çözmek başardı:

protected void Application_BeginRequest() 
{ 
    if (Request.HttpMethod == "OPTIONS") 
    { 
     Response.StatusCode = (int)HttpStatusCode.OK; 
     Response.AppendHeader("Access-Control-Allow-Origin", Request.Headers.GetValues("Origin")[0]); 
     Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); 
     Response.AppendHeader("Access-Control-Allow-Credentials", "true"); 
     Response.End(); 
    } 
} 

Ne bu kod yapar (SEÇENEKLER yanıta eksik başlıkları ekleyin ön kontrol hatası) ön far hataya neden oldu. Benim web API çağırarak farklı kökenli olduğundan ben dinamically tepki olarak kökeni ayarlamak için Request.Headers.GetValues("Origin")[0]) kullanıyorum. Eğer kullanıyorsanız, Ayrıca

var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "*", "*"); 
cors.SupportsCredentials = true; 
config.EnableCors(cors); 

: WebApiConfig.cs yılında

Hala farklı kökenlere belirtilen ama böyle başlıklar ve yöntemleri üzerine joker yanı sıra true SupportsCredentials ayarlayarak, kullanılan AngularJS benim gibi, kimlik bilgilerini kullanmak için $ http'u yapılandırmanız gerekir.Bu, şu şekilde genel olarak yapılandırılabilir:

angular 
.module('Application') 
.config(['$httpProvider', 
    function config($httpProvider) { 
     $httpProvider.defaults.withCredentials = true; 
    } 
]); 

Ve işte bu kadar. Bu benim problemimi çözdü.

1

istenen kökeni izin verilip kontrol etmek için aşağıdaki gibi ICorsPolicyProvider şey kullanarak özel bir özellik oluşturun ya da değil

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = false)] 
    public class EnableCorsForAPIKeysAttribute : 
     Attribute, ICorsPolicyProvider, IFilter 
    { 
     public async Task<CorsPolicy> GetCorsPolicyAsync(
      HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      var corsRequestContext = request.GetCorsRequestContext(); 
      var originRequested = corsRequestContext.Origin; 
      if (await IsValidOrigin(originRequested)) //Check if requested origin is valid or not 
      { 
       // Grant CORS request 
       var policy = new CorsPolicy 
       { 
        AllowAnyHeader = true, 
        AllowAnyMethod = true 
       }; 
       policy.Origins.Add(originRequested); 
       return policy; 
      } 
      else 
      { 
       // Reject CORS request 
       return null; 
      } 
     } 

     public bool AllowMultiple { get {return false;} } 
    } 

Kullanmak için, API denetleyicinize ekleyin

[EnableCorsForAPIKeys] 
public class APIBaseController : ApiController 
{ 
} 
+0

Bu çözüm, tüm kontrolörlere bu notu eklemem gerekmiyor mu? Küresel olarak her şeyi yapılandırabileceğim bir çözüm bulmayı tercih ederim. –

+0

Sanırım bunu yapabildiğiniz global config.Filters.Add (yeni EnableCorsForAPIKeysAttribute()); – Paresh

İlgili konular