73

Buduję aplikację internetową z warstwą usług. Warstwa usług zostanie zbudowana przy użyciu projektu RESTful. Myślimy, że w przyszłości możemy zbudować inne aplikacje (iPhone, Android itp.), Które korzystają z tej samej warstwy usług co aplikacja internetowa. Moje pytanie brzmi - jak zaimplementować logowanie? Myślę, że mam problem z przejściem od bardziej tradycyjnego projektu opartego na czasownikach do projektu opartego na zasobach. Gdybym budował to z SOAPem, prawdopodobnie miałbym metodę o nazwie Login. W REST powinienem mieć zasób. Mam trudności ze zrozumieniem, w jaki sposób należy utworzyć mój identyfikator URI do logowania. Powinno to być coś takiego:Jak zaimplementować logowanie w serwisie WWW RESTful?

http://myservice/ {username} p = {hasło}

EDIT: Z przodu aplikacja end web używa tradycyjnej ramy ASP.NET dla uwierzytelniania. Jednak w pewnym momencie procesu uwierzytelniania muszę zweryfikować dostarczone poświadczenia. W tradycyjnej aplikacji internetowej zrobię przeszukiwanie bazy danych. Ale w tym scenariuszu wywołuję usługę zamiast wykonywać wyszukiwanie w bazie danych. Potrzebuję więc czegoś w usłudze, która sprawdzi poprawność dostarczonych danych uwierzytelniających. Oprócz sprawdzania poprawności dostarczonych poświadczeń, prawdopodobnie potrzebuję również pewnych informacji o użytkowniku po jego pomyślnym uwierzytelnieniu - takich jak pełne imię i nazwisko, identyfikator itp. Mam nadzieję, że dzięki temu pytanie stanie się jaśniejsze.

Albo ja nie myślałem o tym w odpowiedni sposób? Czuję, że mam trudności z prawidłowym opisem mojego pytania.

Corey

Odpowiedz

55

Jak S.Lott wskazał już, mamy dwie złożone rzeczy tutaj: Logowanie i uwierzytelnianie

Uwierzytelnianie jest out-of-zakresem tutaj, jak to jest szeroko omawiane i tam jest wspólne porozumienie. Jednak, czego faktycznie potrzebujemy, aby klient pomyślnie uwierzytelnił się przed usługą RESTful? Racja, jakiś token, nazwijmy to tokenem dostępu.

Klient) Potrzebuję tylko toka dostępu, ale jak uzyskać RESTENCYJNE?
Serwer) Dlaczego po prostu nie tworzyć?
Klient) Jak to możliwe?
Serwer) Dla mnie token dostępu to nic innego jak zasób. W ten sposób utworzę dla ciebie jeden w zamian za nazwę użytkownika i hasło.

W ten sposób serwer może zaoferować adres URL zasobu "/ accesstokens", dla POSTING nazwy użytkownika i hasła, zwracając link do nowo utworzonego zasobu "/ accesstokens/{accesstoken}". Ewentualnie wrócisz dokument zawierający dostępu token a href z linkiem zasobu za:

 
<access-token 
    id="{access token id goes here; e.g. GUID}" 
    href="/accesstokens/{id}" 
/> 

Najprawdopodobniej, nie faktycznie stworzenia dostępu token jako subresource, a tym samym nie będzie zawierała jego href w odpowiedzi.
Jednakże, jeśli to zrobisz, klient może wygenerować link w jego imieniu, czy nie? Nie!
Pamiętaj, że usługi internetowe RESTful naprawdę łączą zasoby w taki sposób, że klient może nawigować bez potrzeby generowania linków do zasobów.

Ostatnie pytanie, które najprawdopodobniej masz, to POST nazwa użytkownika i hasło jako formularz HTML lub dokument, np. XML lub JSON - to zależy ... :-)

+3

Niezupełnie po REST, ale proste i wymiernie lepsze niż inne. Plus dzielone z dobrym humorem. –

+1

Patrick, proponujesz to samo co ta odpowiedź? http://stackoverflow.com/a/1135995/14731 – Gili

+0

Czy 403 jest prawidłowym kodem stanu, gdy nazwa użytkownika i/lub hasło nie pasują? – sevteen

-4

Napotkałem ten sam problem wcześniej. Logowanie nie jest ładnie przełożone na projektowanie oparte na zasobach.

Sposób, w jaki zwykle poradzić jest poprzez logowanie zasobu i przechodzącej nazwę użytkownika i hasło w łańcuchu parametrów, w zasadzie robi

GET na http://myservice/login?u= {username} & p = {hasło}

Odpowiedź jest pewnego rodzaju ciąg sesji lub auth, który można następnie przekazać do innych interfejsów API w celu sprawdzenia poprawności.

Alternatywą dla wykonywania GET na zasobie logowania jest wykonywanie POST, REST purystów prawdopodobnie mnie teraz nie polubi :), i przekazanie w credach ciała. Odpowiedź byłaby taka sama.

+11

hasła? Hasło zwykłego tekstu?Jako ciąg zapytania? Czy naprawdę tak myślisz, czy masz na myśli skrót hasła? –

+0

Dzięki. To ma sens. Oto pytanie uzupełniające - w przypadku dużej aplikacji można utworzyć jedną dużą usługę RESTful dla wszystkiego lub zepsuć różne usługi? Myślałem o usługach tylko w celu uwierzytelnienia, a następnie różnych usług dla różnych modułów mojej aplikacji. Czy są jakieś powody, dla których zrobiłbyś to w taki czy inny sposób? –

+2

S. Lott: To zależy od tego, co próbujesz zrobić. Oczywiście, jeśli potrafisz zrobić skrót, to na wszelki wypadek. Czasami podsumowanie nie jest możliwe. Jeśli jedyną dostępną opcją jest wysłanie hasła w postaci zwykłego tekstu, zrób to za pomocą SSL, w tym przypadku lepiej jest użyć POST niż GET, aby przeglądarka nie pamiętała, co wysłałeś. – Alex

22

Nie "logujesz się". "Uwierzytelniasz". Świat różnicy.

Masz wiele opcji uwierzytelniania.

HTTP Basic, Digest, NTLM and AWS S3 Authentication

  • HTTP Basic i uwierzytelniania Digest. Wykorzystuje to nagłówek HTTP_AUTHORIZATION. To bardzo miłe, bardzo proste. Ale może prowadzić do dużego ruchu.

  • Uwierzytelnienie użytkownika/podpisu. Czasami nazywane uwierzytelnianiem "ID i KEY". Może użyć ciągu zapytania.

    ?username=this&signature=some-big-hex-digest

    To co stawia jak Amazon użytkowania. Nazwa użytkownika to "id". "Klucz" to skrót, podobny do tego używanego do uwierzytelniania HTTP Digest. Obie strony muszą wyrazić zgodę na to, aby kontynuować.

  • Pewne uwierzytelnianie oparte na plikach cookie. Na przykład OpenAM można skonfigurować jako agenta do uwierzytelniania i dostarczania pliku cookie, który może następnie wykorzystać serwer RESTful. Klient powinien najpierw uwierzytelnić, a następnie dostarczyć plik cookie dla każdego żądania RESTful.

+0

Może muszę wyjaśnić moje pytanie. Użytkownicy odwiedzający witrynę nie będą bezpośrednio kontaktować się z usługą RESTful. Będą wchodzić w interakcje z aplikacją internetową. Tak więc, gdy użytkownik próbuje zalogować się do aplikacji internetowej, aplikacja internetowa wykona połączenie z usługą sieciową (przy użyciu kodu C#). Następnie, w oparciu o odpowiedź z serwisu internetowego, kod będzie albo rejestrował je w aplikacji internetowej, albo nie. Czy to ma sens? Nie jestem pewien, czy sugerowane metody uwierzytelniania będą działać, ponieważ przeglądarka użytkownika nie wchodzi bezpośrednio w interakcję z usługą. –

+0

@Corey Burnett: Prawidłowo. Użytkownicy nie mogą wchodzić w interakcje z usługą WWW RESTful. Poprawny. Aplikacje internetowe wywołują usługi sieciowe. Wszystkie te metody zostały zaprojektowane tak, aby aplikacja C# tworzyła żądanie REST z odpowiednimi referencjami i otrzymywała odpowiedź. Usługa internetowa RESTful nigdy nie obsługuje "logowania", ponieważ nie ma sesji. Może obsługiwać uwierzytelnianie, potwierdzając, że żądanie jest ważne. Mamy "fałszywą" prośbę, która odpowiada po prostu za pomocą "200 OK", jeśli referencje są dobre. –

+2

@ S.Lott @Corey Użytkownicy absolutnie mogą wchodzić w interakcje z systemami RESTful. Większość statycznych stron HTML to "usługi" REST. –

0

Ponieważ trochę się zmieniło od 2011 roku ...

Jeśli jesteś otwarty do korzystania z 3rd narzędzia firmy, a nieznacznie odbiegające od odpoczynku nieznacznie interfejs internetowy, rozważ http://shiro.apache.org.

Shiro w zasadzie daje filtr serwletów przeznaczony do uwierzytelniania i autoryzacji. Możesz wykorzystać wszystkie metody logowania wymienione przez @ S.Lott, w tym proste uwierzytelnianie oparte na formularzu.

Przefiltruj pozostałe adresy URL wymagające uwierzytelnienia, a Shiro zajmie się resztą.

Obecnie używam tego w moim własnym projekcie i jak na razie działa on bardzo dobrze.

Tu coś innego ludzie mogą być zainteresowani. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme

1

Wielkie pytanie, dobrze postawione. Naprawdę lubię odpowiedź Patricka.Używam coś podobnego

-/users/{username}/loginsession

POST i GET są obsługiwane. Dlatego wysyłam nową sesję logowania z poświadczeniami, a następnie mogę wyświetlić bieżącą sesję jako zasób przez GET.

Zasób jest sesja logowania, a które mogą mieć dostęp do kodu tokena lub auth, ważności itp

Co dziwne, mój rozmówca MVC sama musi stanowić klucz/okaziciela żeton poprzez nagłówek, aby udowodnić, że ma prawo do próbowania tworzenia nowych sesji logowania, ponieważ strona MVC jest klientem API.

Edit

myślę niektóre inne odpowiedzi i komentarze są tu rozwiązania problemu z out-of-band wspólną tajemnicą i tylko uwierzytelnianie z nagłówkiem. To w porządku w wielu sytuacjach lub w przypadku rozmów serwisowych.

Drugim rozwiązaniem jest przepływ tokena, OAuth lub JWT lub w inny sposób, co oznacza, że ​​"logowanie" zostało już wykonane przez inny proces, prawdopodobnie zwykły interfejs logowania w przeglądarce oparty na formularzu POST.

Moja odpowiedź dotyczy usługi znajdującej się za tym interfejsem, zakładając, że chcesz, aby logowanie i uwierzytelnianie oraz zarządzanie użytkownikami były umieszczane w usłudze REST, a nie w kodzie witryny MVC. Jest to usługa logowania użytkownika.

Umożliwia także innym usługom "zalogowanie się" i uzyskanie wygasającego tokena, zamiast użycia klucza wstępnego, a także skryptów testowych w CLI lub Postman.

+2

Przekaż tokenowi w nagłówku, tak. Przekaż go jako część adresu URL, nie. Adres URL jest szyfrowany w drodze, gdy używasz protokołu HTTPS. Jednak; adres URL jest również przechowywany w historii przeglądarki i dziennikach serwera. Istnieje wiele dobrych powodów do uniknięcia przekazywania danych wrażliwych na bezpieczeństwo w parametrach zapytań adresów URL. – Craig

0

Pierwszą rzeczą, którą należy zrozumieć na temat REST, jest to, że jest to dostęp do zasobów w oparciu o token. W przeciwieństwie do tradycyjnych sposobów dostęp jest przyznawany na podstawie sprawdzania poprawności tokena. W prostych słowach, jeśli masz prawy token, możesz uzyskać dostęp do zasobów. Teraz jest dużo innych rzeczy do tworzenia tokenów i manipulacji.

Na pierwsze pytanie możesz zaprojektować Restfull API. Poświadczenia (nazwa użytkownika i hasło) zostaną przekazane do twojej warstwy usługi. Warstwa serwisowa następnie sprawdza te poświadczenia i przyznaje token.Credentials może być zwykłą nazwą użytkownika/hasłem lub może być certyfikatem SSL. Certyfikaty SSL korzystają z protokołu OAUTH i są bardziej bezpieczne.

Można zaprojektować URI jak to- URI dla tokena request->http://myservice/some-directory/token? (Możesz podać Credentilals w tym identyfikatorze URI dla tokena)

Aby użyć tego tokena dla dostępu do zasobów, możesz dodać to [Authorization: Bearer (token)] do nagłówka http.

Ten token może być używany przez klienta w celu uzyskania dostępu do różnych komponentów warstwy usług. Możesz także zmienić okres ważności tego tokena, aby zapobiec niewłaściwemu użyciu.

Do drugiego pytania można zaliczyć różny token, aby uzyskać dostęp do różnych składników zasobów warstwy usług. W tym celu możesz określić parametr zasobu w tokenie oraz uprawnienia główne oparte na tym polu.

Można również śledzić te linki do Bliższe informacje http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

Powiązane problemy