Problem:
Mamy oparty na Spring MVC interfejs API RESTful, który zawiera poufne informacje. Interfejs API powinien być zabezpieczony, jednak wysyłanie poświadczeń użytkownika (kombinacja użytkownik / hasło) przy każdym żądaniu nie jest pożądane. Zgodnie z wytycznymi REST (i wewnętrznymi wymaganiami biznesowymi) serwer musi pozostać bezstanowy. Interfejs API zostanie wykorzystany przez inny serwer w podejściu typu mashup.
Wymagania:
Klient wysyła żądanie
.../authenticate
(niezabezpieczony adres URL) przy użyciu poświadczeń; serwer zwraca bezpieczny token, który zawiera wystarczającą ilość informacji, aby serwer mógł zweryfikować przyszłe żądania i pozostać bezstanowy. Prawdopodobnie składałoby się z tych samych informacji, co token Remember-Me firmy Spring Security .Klient wysyła kolejne żądania do różnych (chronionych) adresów URL, dołączając wcześniej uzyskany token jako parametr zapytania (lub, co mniej pożądane, nagłówek żądania HTTP).
Od klienta nie można oczekiwać przechowywania plików cookie.
Ponieważ używamy już Springa, rozwiązanie powinno korzystać z Spring Security.
Waliliśmy głowami w ścianę, próbując sprawić, by to zadziałało, więc mam nadzieję, że ktoś już tam rozwiązał ten problem.
Biorąc pod uwagę powyższy scenariusz, w jaki sposób możesz rozwiązać tę konkretną potrzebę?
źródło
Odpowiedzi:
Udało nam się, aby działało dokładnie tak, jak opisano w PO, i mam nadzieję, że ktoś inny może skorzystać z rozwiązania. Oto co zrobiliśmy:
Skonfiguruj kontekst bezpieczeństwa w następujący sposób:
Jak widać, stworzyliśmy niestandardowy
AuthenticationEntryPoint
, który w zasadzie zwraca tylko401 Unauthorized
jeśli żądanie nie zostało uwierzytelnione przez nasz łańcuch filtrówAuthenticationTokenProcessingFilter
.CustomAuthenticationEntryPoint :
AuthenticationTokenProcessingFilter :
Oczywiście
TokenUtils
zawiera poufny (i bardzo specyficzny dla danego przypadku) kod i nie można go łatwo udostępnić. Oto jego interfejs:To powinno zapewnić ci dobry początek. Szczęśliwego kodowania. :)
źródło
validate(...)
metoda). Jest to ważne, ponieważ chcę, aby serwer pozostał bezstanowy. Wyobrażam sobie, że możesz zastosować to podejście bez potrzeby korzystania ze sprężyny.Możesz rozważyć uwierzytelnienie dostępu Digest . Zasadniczo protokół jest następujący:
Cała ta komunikacja odbywa się za pomocą nagłówków, co, jak podkreśla jmort253, jest ogólnie bezpieczniejsze niż przekazywanie wrażliwych materiałów w parametrach adresu URL.
Uwierzytelnianie dostępu Digest jest obsługiwane przez Spring Security . Zauważ, że chociaż dokumenty mówią, że musisz mieć dostęp do hasła w postaci zwykłego tekstu, możesz pomyślnie uwierzytelnić się, jeśli masz skrót HA1 dla swojego klienta.
źródło
Jeśli chodzi o tokeny zawierające informacje, tokeny internetowe JSON ( http://jwt.io ) to doskonała technologia. Główną koncepcją jest osadzenie elementów informacji (oświadczeń) w tokenie, a następnie podpisanie całego tokena, aby weryfikujący koniec mógł zweryfikować, czy oświadczenia są rzeczywiście godne zaufania.
Korzystam z tej implementacji Java: https://bitbucket.org/b_c/jose4j/wiki/Home
Istnieje również moduł Spring (spring-security-jwt), ale nie sprawdziłem, co obsługuje.
źródło
Dlaczego nie zaczniesz używać OAuth z JSON WebTokens
http://projects.spring.io/spring-security-oauth/
OAuth2 jest znormalizowanym protokołem / strukturą autoryzacji. Zgodnie z oficjalną specyfikacją OAuth2 :
Więcej informacji znajdziesz tutaj
źródło