73

Sto costruendo un'applicazione Web con un livello di servizi. Il livello dei servizi verrà creato utilizzando un progetto RESTful. Il pensiero è che in futuro potremo costruire altre applicazioni (iPhone, Android, ecc.) Che utilizzano lo stesso livello di servizi dell'applicazione web. La mia domanda è questa: come posso implementare il login? Penso di avere problemi a passare da un progetto basato su verbo più tradizionale a un progetto basato su risorse. Se stavo costruendo questo con SOAP probabilmente avrei un metodo chiamato Login. In REST dovrei avere una risorsa. Sto avendo difficoltà a capire come dovrei costruire il mio URI per un login. Dovrebbe essere qualcosa di simile:Come implementare l'accesso in un servizio web RESTful?

http://myservice/ {username} p = {} Password

EDIT:? L'applicazione front end web utilizza il framework ASP.NET tradizionale per l'autenticazione. Tuttavia, a un certo punto del processo di autenticazione devo convalidare le credenziali fornite. In un'applicazione web tradizionale vorrei fare una ricerca nel database. Ma in questo scenario sto chiamando un servizio invece di fare una ricerca nel database. Quindi ho bisogno di qualcosa nel servizio che convalidi le credenziali fornite. E oltre a convalidare le credenziali fornite, probabilmente ho bisogno anche di una sorta di informazione sull'utente dopo che si sono autenticati con successo - cose come il loro nome completo, il loro ID, ecc. Spero che questo chiarisca la domanda.

O non sto pensando a questo nel modo giusto? Mi sembra di avere difficoltà a descrivere correttamente la mia domanda.

Corey

risposta

55

Come S. Lott ha sottolineato già, abbiamo un due cose piegati qui: Login e autenticazione

autenticazione è out-of-scope qui, in quanto questo è ampiamente discusso e non v'è un accordo comune. Tuttavia, che cosa è effettivamente necessario per un client autenticarsi con successo su un servizio Web RESTful? Giusto, una specie di token, chiamiamolo token di accesso.

Client) Quindi, tutto ciò di cui ho bisogno è un token di accesso, ma come ottenere tale RESTfully?
Server ) Perché non crearlo semplicemente?
Client) Come arriva?
Server ) Per me un token di accesso non è altro che una risorsa. Quindi, ne creerò uno per te in cambio del tuo nome utente e password.

Pertanto, il server potrebbe offrire l'URL della risorsa "/ accesstokens", per POSTing nome utente e password, restituendo il collegamento alla risorsa appena creata "/ accesstokens/{accesstoken}". In alternativa, si restituisce un documento che contiene il token di accesso e di a href con il link della risorsa:

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

Molto probabilmente, in realtà non creare l'accesso token come subresource e, quindi, non includerà il suo href nella risposta.
Tuttavia, se lo fa, il client potrebbe generare il collegamento per suo conto o no? No!
Ricordate, i servizi web veramente RESTful collegano le risorse insieme in modo che il client possa navigare da solo senza la necessità di generare alcun collegamento di risorse.

L'ultima domanda che probabilmente si ha è se POST il nome utente e la password come un modulo HTML o come un documento, ad es. XML o JSON - dipende ... :-)

+3

Non perfettamente seguendo REST, ma un semplice e misurabilmente migliore di altri. Plus condiviso con buon umore. –

+1

Patrick, stai proponendo la stessa cosa di questa risposta? http://stackoverflow.com/a/1135995/14731 – Gili

+0

Il codice di stato 403 corretto quando username e/o password non corrispondono? – sevteen

-4

Ho affrontato lo stesso problema prima. Il login non si adatta bene al design basato su risorse.

Il modo in cui di solito gestirlo è di avere risorsa Accesso e passando il nome utente e la password nella stringa di parametri, in fondo facendo

salire sul http://myservice/login?u= {username} & p = {Password}

La risposta è un tipo di sessione o stringa di autenticazione che può essere passata ad altre API per la convalida.

Un'alternativa a fare GET sulla risorsa di accesso sta facendo un POST, i puristi di REST probabilmente non mi piaceranno ora :) e passando i crediti nel corpo. La risposta sarebbe la stessa.

+11

password? Password di testo normale?Come una stringa di query? Lo intendevi davvero, o intendi un riassunto della password? –

+0

Grazie. Ciò ha senso. Ecco una domanda di follow-up: per un'applicazione di grandi dimensioni crei un grande servizio RESTful per tutto o suddividilo in servizi diversi? Stavo pensando di avere un servizio solo per l'autenticazione e quindi diversi servizi per i diversi moduli della mia applicazione. Ci sono motivi per cui lo farei o non lo farei in un modo o nell'altro? –

+2

S. Lott: Dipende da cosa stai cercando di fare. Certo se puoi fare un digest, allora con tutti i mezzi. A volte un riassunto non è possibile. Se l'unica opzione a tua disposizione è l'invio di una password in testo semplice, fallo su SSL, in questo caso è anche meglio usare un POST piuttosto che GET per impedire al browser di ricordare ciò che hai inviato. – Alex

22

Non si effettua il "login". Tu "autentichi". Mondo della differenza.

Hai molte alternative di autenticazione.

HTTP Basic, Digest, NTLM and AWS S3 Authentication

  • HTTP di base e l'autenticazione Digest. Questo utilizza l'intestazione HTTP_AUTHORIZATION. Questo è molto bello, molto semplice. Ma può portare a molto traffico.

  • Autenticazione nome utente/firma. A volte chiamata autenticazione "ID e KEY". Questo può usare una stringa di query.

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

    Questo è ciò che pone come l'uso di Amazon. Il nome utente è "id". La "chiave" è un digest, simile a quello utilizzato per l'autenticazione HTTP Digest. Entrambe le parti devono concordare sul digest per procedere.

  • Un tipo di autenticazione basata su cookie. OpenAM, ad esempio, può essere configurato come agente per l'autenticazione e fornire un cookie che il server Web RESTful può quindi utilizzare. Il client dovrebbe prima autenticarsi e quindi fornire il cookie con ciascuna richiesta RESTful.

+0

Forse ho bisogno di chiarire la mia domanda. Gli utenti che visitano il sito Web non interagiranno direttamente con il servizio RESTful. Interagiranno con l'applicazione web. Pertanto, quando un utente tenta di accedere all'applicazione Web, l'applicazione Web effettuerà una chiamata al servizio Web (utilizzando il codice C#). Quindi, in base alla risposta del servizio Web, il codice li accederà o meno all'applicazione Web. Ha senso? Non sono sicuro che i metodi di autenticazione suggeriti funzioneranno poiché il browser dell'utente non interagisce direttamente con il servizio. –

+0

@Corey Burnett: corretto. Gli utenti non possono interagire con un servizio web RESTful. Corretta. Le applicazioni Web chiamano i servizi Web. Tutti questi metodi sono progettati in modo specifico in modo che un'applicazione C# effettui una richiesta RESTful con credenziali appropriate e ottenga una risposta. Un servizio web RESTful non gestisce mai il "login" perché non ha sessioni. Può gestire l'autenticazione accettando che la richiesta sia valida. Abbiamo una richiesta "fittizia" che risponde semplicemente con un "200 OK" se le credenziali sono buone. –

+2

@ S.Lott @Corey Gli utenti possono assolutamente interagire con i sistemi RESTful. La maggior parte dei siti Web HTML statici sono "servizi" RESTful. –

0

Dal momento che un po 'è cambiato dal 2011 ...

Se siete aperti a utilizzare uno strumento di terze parti, e leggermente deviare dal REST un po' per l'interfaccia utente web, prendere in considerazione http://shiro.apache.org.

Shiro fornisce fondamentalmente un filtro servlet destinato all'autenticazione e all'autorizzazione. È possibile utilizzare tutti i metodi di accesso elencati da @ S.Lott, inclusa un'autenticazione basata su form semplice.

Filtra gli URL di resto che richiedono l'autenticazione e Shiro farà il resto.

Attualmente sto usando questo nel mio progetto e ha funzionato abbastanza bene per me finora.

Ecco qualcosa che la gente altro potrebbe essere interessato. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme

1

Grande questione, ben posto. Mi piace molto la risposta di Patrick.Io uso qualcosa come

-/utenti/{username}/loginsession

Con POST e GET essere manipolati. Quindi inserisco una nuova sessione di accesso con le credenziali e posso quindi visualizzare la sessione corrente come una risorsa tramite GET.

La risorsa è una sessione di login, e che possono avere un codice token o autenticazione, scadenza, ecc

Stranamente l'accesso, il mio interlocutore MVC deve presentarsi un token di chiave/portatore tramite un colpo di testa per dimostrare che ha il diritto di provare e creare nuove sessioni di accesso poiché il sito MVC è un client dell'API.

Modifica

Penso che alcune altre risposte e commenti qui stanno risolvendo il problema con una banda di out-of-segreto condiviso e solo l'autenticazione con un colpo di testa. Questo va bene in molte situazioni o per le chiamate service-to-service.

L'altra soluzione è il flusso di un token, OAuth o JWT o altro, il che significa che il "login" ha già avuto luogo da un altro processo, probabilmente una normale interfaccia utente di login in un browser che si basa su un modulo POST.

La mia risposta è per il servizio che si trova dietro quell'interfaccia utente, presupponendo che si desidera il login e l'autenticazione e la gestione degli utenti inseriti in un servizio REST e non nel codice MVC del sito. È il servizio di accesso dell'utente.

Consente inoltre ad altri servizi di "accedere" e ottenere un token in scadenza, anziché utilizzare una chiave precondivisa, nonché script di test in una CLI o in un postino.

+2

Passa il token in un'intestazione, sì. Passalo come parte dell'URL, no. L'URL è in transito crittografato quando si utilizza HTTPS. Però; l'URL è anche memorizzato nella cronologia del browser e nei log del server. Esistono molti buoni motivi per evitare di trasmettere dati sensibili alla sicurezza nei parametri di query URL. – Craig

0

La prima cosa da capire su REST è che si tratta di un accesso a una risorsa basata su token. A differenza dei metodi tradizionali, l'accesso è concesso in base alla convalida del token. In parole semplici se hai il token giusto, puoi accedere alle risorse. Ora ci sono molte altre cose per la creazione e la manipolazione di token.

Per la prima domanda, è possibile progettare un'API Restfull. Le credenziali (nome utente e password) verranno passate al tuo livello di servizio. Il livello di servizio quindi convalida queste credenziali e concede un token. Le credenziali possono essere semplici username/password o possono essere certificati SSL. I certificati SSL utilizzano il protocollo OAUTH e sono più sicuri.

È possibile progettare l'URI come questo - URI per richiesta token->http://myservice/some-directory/token? (È possibile passare Credentilals in questo URI per Token)

Per utilizzare questo token per l'accesso alle risorse è possibile aggiungere questo [Autorizzazione: Bearer (token)] all'intestazione http.

Questo token può essere utilizzato dal cliente per accedere a diversi componenti del livello di servizio. È inoltre possibile modificare il periodo di scadenza di questo token per impedire l'uso improprio.

Per la seconda domanda, una cosa che puoi fare è che tu concedi un token diverso per accedere a diversi componenti di risorse del tuo livello di servizio. Per questo è possibile specificare il parametro della risorsa nel token e la grande autorizzazione basata su questo campo.

Potete anche seguire questi link per Ulteriori informazioni 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

Problemi correlati