2014-12-09 16 views
5

Mam tej aplikacji, gdzie chciałbym ustawić moje niestandardowe nagłówki w Web.Config, niestety nie zawsze jest to dowód głupi.Problemy z CORS w ASP.NET

<customHeaders> 
    <add name="Access-Control-Allow-Origin" value="*" /> 
    <add name="Access-Control-Allow-Methods" value="*" /> 
    <add name="Access-Control-Allow-Headers" value="*" /> 
    </customHeaders> 

Powyższy zestaw i iteracje nim takie jak

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

nie pracował pracował dla mnie w ogóle scenariusze. Od tej pory to ustawienie działa w około 50% maszyn testowych i daje 405 Method Not Allowed w innych.

Alternatywę można ustawić w WebApiConfig.cs i odkomentować niestandardowe nagłówki w Web.config.

//Web API Cross origin requests - Enable 
    var cors = new EnableCorsAttribute("*", "*", "*"); 
    config.EnableCors(cors); 

Dlaczego istnieje tak wiele dwuznaczności w tym i skąd mam wiedzieć na pewno, gdzie CORS będzie działać przez cały czas? Naprawdę jestem zainteresowany ustawianiem CORS na Web.config tylko dlatego, że chciałbym elastyczności jego modyfikacji w wdrożonej wersji.

Odpowiedz

13

wierzę, że „random” problem występuje, ponieważ nie jesteś manipulowania inspekcji wstępnej Optionsżądań dla PUT i Deleteczasowników.

Dla dwóch czasowników wymienionych powyżej dodatkową życzenie jest generowany, Options, do którego Web API potrzeby reagowania w celu potwierdzenia, że ​​rzeczywiście jest skonfigurowany do obsługi CORS.

Aby sobie z tym poradzić, wystarczy wysłać pustą odpowiedź . Można to zrobić w środku swoich działań, czy można to zrobić globalnie tak:

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

Ta dodatkowa kontrola dodano w celu zapewnienia, że ​​stary APIs, które zostały zaprojektowane, aby przyjmować tylko GET i POST żądania nie zostaną wykorzystane. Wyobraź sobie wysłanie żądania DELETE do API zaprojektowanego, gdy ten czasownik nie istnieje. Rezultatem jest nieprzewidywalny, a wyniki mogą być niebezpieczne.

Również w web.config, należy określić metody zamiast korzystania *

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

Tak, to wydaje się problem. Problem wydaje się przypadkowy, ale z tego, co przeczytałem z twojego postu, wydaje się, że tak naprawdę nie jest. Czy możesz wyjaśnić powód? – Shouvik

+0

Ta dodatkowa kontrola została dodana w celu zapewnienia, że ​​stare API skonfigurowane do akceptowania tylko żądań GET i POST nie będą wykorzystywane. Wyobraź sobie wysłanie komendy DELETE do API zaprojektowanego, gdy ten czasownik nie istnieje. Wynik jest niepewny i może spowodować poważne problemy z danymi za tym API. –

+0

Działa doskonale. – shammelburg

0

Nie ma niejednoznaczność z CORS, masz kilka spraw, które trzeba myśleć o

1- jeżeli chcesz włączyć CORS dla swoich Web APIs tylko korzystać z biblioteki "Microsoft.AspNet.WebApi.Cors".

2- jeśli chcesz włączyć CORS dla całej witryny (w tym Web APIs, SignalR, ..etc) użyj biblioteki "Microsoft.Owin.Cors".

użycie dowolnej biblioteki z powyższych 2 zdecydowanie zadziała, a cors zostanie włączone, teraz jeśli chcesz skonfigurować adresy URL, możesz to zrobić z pliku bazy danych/config, więc gdy twoja aplikacja uruchomi URL, który podałeś do EnableCors na przykład może pochodzić z pliku bazy danych/config, ale w dolnej linii jest unikanie dodawania nagłówków cors do pliku web.config.

Aby wiedzieć, jak włączyć CORS dla swojego internetowego interfejsu API, możesz zapoznać się z moim artykułem here, który umożliwia CORS dla interfejsów API sieci Web i używania ich z klienta AngularJS.

Nadzieję, że pomaga.

0

Dla każdego, kto to czyta, może to pomóc.

Nawet z następującego kodu startowego

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

musiałem explcitly dodać czasowniki metody działania Api Web:

[Route("sanity")] 
[HttpOptions] 
[HttpPost] 
public List<PostImportView> Sanity(SanityFilter filter) 
{ 
    .... 

Całkiem bez sensu i denerwujące