10

Mam wbudowany mechanizm REST API backend z Spring MVC i zabezpieczony podstawową funkcją Auth z Spring Security.JQuery cross domain basic auth call

Chciałbym wykonać wywołanie ajax w domenie krzyżowej do API REST z klientów JavaScript. Nie chcę używać JSONP, ponieważ nie chcę ograniczać się do wywołań GET. Używam CORS i umieściłem odpowiednie nagłówki po stronie serwera.

Załóżmy, że mój interfejs API REST znajduje się w domenie localhost: 8087, a mój klient na localhost: 8086, który jest połączeniem międzydomenowym.

W moim klientem JavaScript, robię ajax połączenia z jQuery:

<script> 
     $.ajax ({ 
      url: "http://localhost:8087/SpringMVC/users/user1", 
      beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", "Basic xxxxxxxxxxxx"); }, 
      success: function(val) { console.log(val); alert("success" + val); }, 
      error: function(val) { console.log(val); alert("error" + val); } 
     }); 
</script> 

Moim problemem jest to, że jQuery nie wysyła nagłówek Authorization w żądaniu HTTP i nie wiem dlaczego. Nie rozumiem, ponieważ robię to w metodzie beforeSend, więc powinno być wewnątrz żądania HTTP. Wynik: mam błąd 401.

Kiedy próbuję skrypt z tej samej domeny localhost: 8087, która nie jest już domeną, nie mam problemu.

Jak to jest możliwe?

Mój skrypt to tylko test. Nie zamierzam umieszczać mojej nazwy użytkownika/hasła po stronie klienta. Ale chcę przetestować, jak wykonać wywołania ajax do podstawowego autoodpornego REST API. Wyobrażam sobie, że muszę wysłać po stronie serwera, aby zabezpieczyć moją nazwę użytkownika/hasło, interfejs API REST odsyła mnie do pliku cookie i nie muszę już przekazywać nazwy użytkownika/hasła do kolejnych wywołań ajaxów do interfejsu API REST. Czy mam rację ?

Przetestowałem mój interfejs REST API z klientem REST zaawansowanego systemu Windows i działa on w ten sposób. W przypadku pierwszego żądania muszę przekazać nagłówek autoryzacji. Wtedy nie jest potrzebne. Czy to też powinno działać w moim kliencie sieciowym javascript? Zamierzam użyć Node.JS z Backbone do jego zbudowania.

Wielkie dzięki.

EDIT2: Wygląda na to, że jest to problem z przeglądarką CORS. Dodałem nagłówek Access-Control-Allow-Methods dla metody OPTIONS po stronie serwera i działa on w Chrome. Mam dostęp do odpowiedzi JSON bez żadnego błędu. Ale nadal potrzebuję użyć nagłówka autoryzacji dla następnych żądań. Jak powiedzieć jQuery, aby używał wysłanego cookie?

A kiedy próbuję z Firefoksa 11, nie mam dostępu do odpowiedzi json i mam błąd:

"NetworkError: 401 Non-Autorisé - http://localhost:8087/SpringMVC/users/user1" 
+0

Czy używasz base64 do kodowania swojej nazwy użytkownika/hasła? –

+0

Tak, wstawiam xxxxxxxx zamiast prawdziwej nazwy użytkownika: hasło. – rico

Odpowiedz

8

Podobno, Chrome i Firefox leczenia Krzyż domeny żąda trochę inaczej. Przed wykonaniem żądania domeny krzyżowej wykonują to, co nazywa się żądaniem "preflight" przy użyciu metody HTTP OPTIONS. Różnica między przeglądarkami Chrome i Firefox polega na tym, że Chrome wysyła również nagłówek Authorization z danymi uwierzytelniającymi, podczas gdy Firefox nie.

To pozostaje problem konfiguracji Spring Security. Mój adres url/users/* jest zabezpieczony dla wszystkich metod HTTP, w tym OPCJI. W przypadku Firefoksa, ponieważ nagłówek Authorization nie jest wysyłany, moje żądanie nie jest autoryzowane. Jeśli ograniczę mój bezpieczny adres url/users/* tylko do metody GET, to działa doskonale w Firefoksie.Musiałem więc tylko dodać, że w moim wiosennym config Bezpieczeństwo:

<intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()" method="GET"/> 

Potem mam wybór: mogę dodać inne metody należy zabezpieczyć w przechwytującym URL, z wyjątkiem opcji, czy mogę ograniczyć HTTP wywołanie metody GET w moim kontroler Spring MVC, który będzie nawet traktować moje połączenia OPTIONS zgodnie z Javadoc. Wybrałem drugie rozwiązanie. Ale jeśli ktoś znajdzie rozwiązanie, które zmusi Firefoksa do wysłania danych uwierzytelniających, takich jak Chrome, byłoby wspaniale i wybrałbym tę.

2

Inną opcją dla scenariusza konfiguracji Wiosna zabezpieczeń przedstawiony przez Rico byłoby:

<http ... use-expressions="true"> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="permitAll" method="OPTIONS"/> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()"/> 
    ... 
</http> 

HTTP OPCJE wnioski zawsze przechodzą przez uwierzytelnianie i każda inna metoda HTTP nie będzie.

Uwaga atrybut use-expressions XML ustawiony prawdziwej w <http> elementu. Wiosna Security następnie oczekiwać atrybuty access tych <intercept-url> elementy zawierają wiosna EL wyrażenia, jak permitAll i isAuthenticated().

Powiązane problemy