Autoryzacja i uwierzytelnianie REST API (web + mobile)
Czytałem o oAuth, Amazon REST API, HTTP Basic / Digest i tak dalej, ale nie mogę dostać tego wszystkiego do "jednego kawałka". Jest to prawdopodobnie najbliższa sytuacja- Tworzenie API dla aplikacji mobilnych-uwierzytelnianie i autoryzacja
Chciałbym zbudować API-centric website-service. Tak więc (na początku) miałbym API w centrum i website (PHP + MySQL) połączyłbym się przez cURL, Android iiPhone poprzez swoją sieć interfejsy. Więc 3 głównych klientów - 3 klucze API. Każdy inny programista może również rozwijać się za pośrednictwem interfejsu API i otrzyma własny klucz API. Działania API będą akceptowane/odrzucane na podstawie statusu poziomu użytkownika, jeśli jestem administratorem, mogę cokolwiek usunąć itp., wszystkie inne mogą manipulować tylko danymi lokalnymi (konta).
Po pierwsze, autoryzacja-czy powinienem użyć oAuth + xAuth lub mojej własnej implementacji (patrz http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)? Jak rozumiem, na użytkownik usługi Amazon jest = = użytkownik API (mieć klucz API) . W mojej usłudze muszę rozdzielić konto użytkownika standardowego (tego, który zarejestrował się na stronie) i konta dewelopera (który powinien mieć swój klucz API).
Więc najpierw musiałbym autoryzować klucz API , a następnie uwierzytelnić samego Użytkownika . Jeśli używam programu Amazon do sprawdź klucze API dewelopera( Autoryzuj ich aplikację), którego sheme powinienem użyć do uwierzytelniania użytkowników?
Czytałem o uzyskaniu tokena przez api.example.org/auth
po (przez HTTPS, HTTP Basic) publikowaniu mojej nazwy użytkownika i hasła, a następnie przekazywaniu go na każde następne żądanie. Jak zarządzać tokenami, jeśli jestem zalogowany jednocześnie na Android i stronie internetowej ? Co z man-in-the-middle-attack Jeśli używam SSL tylko na pierwsze żądanie (gdy nazwa użytkownika i hasło są przesyłane) i po prostu HTTP na każdym innym? Czy to nie jest problem w tym przykładzie hasło chroniące usługę REST?
1 answers
Jak zawsze, najlepszym sposobem ochrony klucza jest nie przesyłanie go.
To powiedziawszy, Zazwyczaj używamy schematu, w którym każdy" klucz API " składa się z dwóch części: niezajmowanego identyfikatora (np. 1234) i tajnego klucza (np. byte[64]).
- jeśli rozdajesz klucz API, przechowuj go (solone i zaszyfrowane) w sobie baza danych serwisu.
- Jeśli rozdajesz konta użytkowników (chronione hasłem), przechowuj hasła (solone i hashowane) w bazie danych twojego serwisu
Teraz, gdy konsument pierwszy dostęp do API, aby połączyć, mieć go
- Wyślij parametr "username" ("john.doe " nie tajne)
- Wyślij parametr " APIkeyID "("1234", nie tajne)
And give him back
- sole z twojej bazy danych (w przypadku, gdy jeden z parametrów jest zły, wystarczy oddać trochę soli powtarzalnej-np. sha1 (username+"notverysecret").
- znacznik czasu serwera
Konsument powinien przechowywać sól przez czas trwania sesji do utrzymuj wszystko szybko i sprawnie, a on powinien obliczyć i zachować przesunięcie czasu między Klientem a serwerem.
Konsument powinien teraz obliczyć salted hashes klucza API i hasła. W ten sposób konsument ma dokładnie takie same skróty dla hasła i klucza API, jak to, co jest przechowywane w bazie danych, ale bez niczego seceret kiedykolwiek przechodzi przez przewód.
Teraz, gdy konsument subseqently uzyskuje dostęp do twojego API, aby wykonać prawdziwą pracę, miej go
- Wyślij " nazwę użytkownika" parametr ("john.doe " nie tajne)
- Wyślij parametr " APIkeyID "("1234", nie tajne)
- Wyślij parametr " RequestSalt "(bajt[64], losowy, nie tajny)
- Wyślij parametr "RequestTimestamp" (obliczony na podstawie czasu klienta i znanego offsetu) W tym celu prosimy o kontakt z Działem obsługi klienta pod adresem
Serwer nie powinien akceptować znaczników czasu więcej niż powiedzmy 2 sekundy w przeszłości, aby było to bezpieczne przed powtórką do ataku.
Serwer może teraz obliczyć ten sam hash (passwordhash+request_salt+request_timestamp+apikeyhash) co klient i upewnić się, że
- Klient zna klucz API,
- Klient zna poprawne hasło
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-22 00:06:59