2015-05-22 18 views
17

buduję kątowym aplikację, który współdziała z API zbudowany z ASP.NET Web API 2. Używam podstawowego uwierzytelniania poprzez wysłanie Authorization nagłówek z każdego wniosku, który wymaga uwierzytelniania:Unikanie inspekcji wstępnej OPCJE wnioski z CORS

kątowa urywek:

$http.defaults.headers.common['Authorization'] = authHeader; 

Zapytanie:

Accept:application/json, text/javascript 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8 
Access-Control-Max-Age:1728000 
Authorization:Basic [base64 encoded credential couplet here] 
Connection:keep-alive 
DNT:1 
Host: blah.com 
Origin:http://localhost:9000 
Referer:http://localhost:9000/ 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/53 

Wszystko działa OKAY, ale żądanie preflight OPTIONS jest wysyłane z każdym żądaniem GET lub POST. Ma to znaczący wpływ na postrzeganą prędkość aplikacji. Zrobiłem dużo lektury "prostych żądań" CORS i wydaje się, że w celu uniknięcia budzącej lęk prośby preflight OPTIONS należy unikać dodawania niestandardowych nagłówków do moich żądań. Próbowałem wielu innych rzeczy, takich jak wysyłanie Content-Type z text/plain, ale wydaje się, że nagłówek Authorization jest rzeczą, która narusza wymóg "Proste żądanie" CORS.

Wygląda więc na to, że może być konieczne przeniesienie interfejsu API w celu użycia uwierzytelniania/autoryzacji opartego na tokenach. Aby uniknąć żądań preflight, wydaje mi się, że będę musiał umieścić token w ciągu zapytania. Jest to w porządku, ponieważ jest to tylko niewielka wewnętrzna aplikacja internetowa, do której dostęp ma tylko kilku użytkowników. Zamierzam wdrożyć buforowanie w odpowiedziach kontrolerów. Ponieważ każde żądanie do działania kontrolera będzie miało inny token w zapytaniu kursowym na podstawie aktualnie uwierzytelnionego użytkownika, czy to spowoduje, że buforowanie będzie bezużyteczne?

Więc:

  1. Jak uniknąć żądania inspekcji wstępnej (przy użyciu nagłówków zwyczaj zezwolenia, jeśli to w ogóle możliwe)
  2. Jeśli 1.) nie jest to możliwe, i przenieść do tokena uwierzytelniania opartego będę w stanie Odpowiedzi interfejsu API pamięci podręcznej dla działań kontrolera
  3. Jakie są najpowszechniej stosowane metody, aby uniknąć żądań preflight, ale także aby bezpiecznie uwierzytelnić użytkowników?

nb Wiem, że istnieje kilka innych wątków na SO i gdzie indziej w internecie dotyczące tego, ale żaden z nich nie wydają się stanowić ostateczną odpowiedź czy jest to możliwe, aby uniknąć inspekcji wstępnej prośby o GET s oraz POST s przy użyciu niestandardowych nagłówków autoryzacji HTTP.

+1

1.) Nie jest jeszcze możliwe we wszystkich przeglądarkach i metodach HTTP: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests – tyler

+1

Powinieneś być w stanie użyć [XMLHttpRequest zCredentials] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials), aby wysłać niepotwierdzone żądanie z plikiem cookie autoryzacji. – dave

Odpowiedz

10

myślę tego postu (How to apply CORS preflight cache to an entire domain) dość dużo mówi wszystko - nie ma wiele można zrobić to

Jedno proste rozwiązanie jest dodanie reverse proxy do proxy/serwer WWW służąc swoją kątową app (np. nginx) do kierowania połączeń RESTful za pośrednictwem tej samej domeny, np appdomain.com/api -> apidomain.com.

+1

Dzięki Reto! Chociaż bardzo chciałbym uporządkować całą sprawę preflightów w odpowiedni sposób, ostatecznie zdecydowałem się na tę odpowiedź. Okazuje się, że możesz skonfigurować odwrotne proxy w usługach IIS i witrynie Azure, więc mój klient będzie również hostowany w aplikacji internetowej Azure z przekazywaniem lokalnych żądań '/ api' do drugiej aplikacji internetowej Azure obsługującej interfejs API. Numer referencyjny: http://ruslany.net/2014/05/using-azure-web-site-as-a-reverse-proxy/ – adaam

2

Inne rozwiązanie, które wydaje się działać dobrze dla mnie. Zamiast konfigurowania proxy i konieczności kierowania do tej samej domeny, możliwe jest zwrócenie żądania preflight bezpośrednio z nginx, a tym samym skrócenie czasu wymaganego przez żądanie inspekcji wstępnej do zaledwie kilku milisekund.

Oto prosty fragment, którego można używać z nginx.

location/{ 
    if ($request_method = 'OPTIONS') { 
     add_header 'Access-Control-Allow-Origin' '*'; 
     add_header 'Access-Control-Allow-Credentials' 'true'; 
     add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; 
     add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization'; 
     add_header 'Access-Control-Max-Age' 1728000; 
     add_header 'Content-Type' 'text/plain charset=UTF-8'; 
     add_header 'Content-Length' 0; 
     return 204; 
    } 
} 

Gdy żądanie inspekcji wstępnej jest udany, to wtedy możliwe jest prosty dodatek "Access-Control-Allow-Origin" i innych niezbędnych rzeczy do 'get', wniosków 'post', etc ...