2010-06-25 12 views
5

Ho scritto un servlet RESTful e lo sviluppatore dell'interfaccia utente desidera salvare lo stato di accesso sul server.Attaccare le mie pistole REST o rompere l'apolidia? Consigli necessari

Ha fatto questa strana affermazione: "Non ho riscontrato un'implementazione REST di produzione che è puro REST. Quelli che ho visto tutti hanno avuto il server mantenere una sessione."

Trovo che sia difficile da accettare. Prima di tutto c'è il tecnicismo che ci sono un sacco di semplici pagine HTTP là fuori, tutte semplicemente RESTful. In secondo luogo, sì, ci sono implementazioni non RESTful etichettate come RESTful, proprio come c'è l'ottone etichettato "oro". Terzo, solo perché tutti gli altri salta giù da un ponte non significa che dovrei.

Sfondo: È un'applicazione Web Ajax JavaScript che utilizza l'autenticazione HTTPS e di base. Per evitare la solita finestra di popup di accesso al browser (non personalizzabile), l'applicazione mostra una schermata di accesso con il logo del prodotto e le caselle di testo per nome e password. Il nome e la password sono memorizzati nel documento e inviati nell'intestazione Autorizzazione per ogni richiesta. Se si aggiorna la pagina, il nome e la password vengono persi e l'utente deve reinserirli nuovamente. Questo è considerato un bug; lo sviluppatore dell'interfaccia utente desidera essere in grado di premere il pulsante di aggiornamento senza fornire nuovamente la password.

Quindi lo sviluppatore desidera utilizzare un cookie o una sessione JSP. Abby, è vero che alla fine ogni implementazione REST mantiene lo stato dell'applicazione sul server? O c'è un modo per risolvere questo problema e mantenere ancora la mia purezza RESTful?

+0

+1 per gli argomenti solidi che seguono "Trovo che sia difficile da accettare". – Sjoerd

+3

Cosa è più importante per te? Mantenimento della cosiddetta purezza o creazione di una buona applicazione con la funzionalità desiderata? Stai passando le credenziali avanti e indietro attraverso il filo? Se avessi incontrato un'app che mi obbligava a reinserire le mie credenziali ad ogni aggiornamento della pagina, sarei da tempo scomparsa. – DOK

+2

@DOK Non si tratta di purezza, si tratta di prendere decisioni informate. La scelta di costruire un sistema che abbia interazioni stateless ha alcune caratteristiche molto desiderabili. Certo, rende alcune cose più difficili, ma questo è un compromesso da considerare. A volte il guadagno a lungo termine richiede dolore a breve termine. Mi rendo conto che la società di oggi è tutta una questione di gratificazione immediata, ma c'è un prezzo da pagare per questo. –

risposta

3

Credo che per ragioni pratiche (principalmente abilità navigabili) è necessario distinguere tra applicazione Stato e autenticazione Stato. Non riesco a pensare a nessun meccanismo di autenticazione che non mantenga una qualche forma di stato sul lato server.

Ciò che importa è come è disaccoppiato dall'applicazione. Ad esempio, HTTP Digest conserva una qualche forma di stato sul server, ma questo è chiaramente estratto come parte della normale negoziazione WWW-Authenticate e Authorization dell'intestazione. Poiché la maggior parte dei browser lo supportano in modo nativo, questo è ortogonale all'applicazione e come tale non infrange il principio di apolidia di REST.

Oggigiorno, poiché gli utenti hanno alcune aspettative estetiche che l'autenticazione di Basic/Digest HTTP non si incontra nei browser, i siti Web tendono a utilizzare l'autenticazione basata su moduli e successivamente i cookie. Per essere onesti è più che solo il modo in cui appare, è anche una questione di usabilità (ad esempio "dimentica la tua password", anche se potrebbe essere nel corpo di una risposta 401) e sicurezza. I browser non ti consentono di disconnettersi facilmente dall'autenticazione di base/digest/certificato, a meno che non sia fatto interamente in Ajax all'interno di una singola pagina, come già accennato, e ciò può aiutare i CSRF.

Penso che i cookie siano accettabili per l'autenticazione, ma assicurati di non memorizzare le variabili relative alle applicazioni nella sessione.

È possibile leggere alcuni dei Roy Fielding's comments on the topic:

autenticazione è ortogonale. I cookie sono anche ortogonali quando sono utilizzati semplicemente per la negoziazione del contenuto o l'autenticazione . Tuttavia, l'autenticazione di Cookie non è consentita in REST perché manca di visibilità, il che causa problemi di sicurezza perché gli altri componenti non sanno che sono informazioni sensibili .

EDIT (ulteriori commenti sugli aspetti di sicurezza):

mi rendo conto i commenti di Roy Fielding nel messaggio che ho citato è contro i cookie per motivi di sicurezza. Ha ragione, certo. Tuttavia, a mio parere, è più difficile proteggere contro CSRF tramite Basic/Digest/Cert (che non era realmente sul radar nel 2003, data di quel messaggio) che contro il furto di cookie. Dipende dall'implementazione, ovviamente. Non esiste una soluzione perfetta, ma se si utilizzano i cookie, utilizzare i cookie sicuri, su HTTPS.

+0

Avrei dovuto dire "qualsiasi meccanismo di autenticazione * sicuro *" nel primo paragrafo. – Bruno

+0

Bruno, grazie per aver reso chiara questa distinzione. –

+0

Bruno, in risposta a ciò che hai aggiunto, è possibile averlo in entrambe le direzioni. Il documento potrebbe contenere l'ID dell'utente, ma i cookie potrebbero essere utilizzati per decidere se rifiutare il documento come inautentico anziché agire su di esso. –

2

Non vedo alcun problema con l'utilizzo di un cookie per mantenere queste informazioni sul lato client. I cookie diventano un problema solo quando vengono utilizzati come puntatori ad uno stato di sessione lato server.

La cosa principale che devi preoccuparti è la sicurezza delle informazioni nel cookie. Probabilmente non si vuole mettere la password in chiaro nel cookie :-)

+0

Una tecnica consiste nell'utilizzare un tipico cookie di sessione e memorizzare l'autenticazione sul lato server. Funziona bene per ASP.NET, quindi mi aspetto che dovrebbe essere un approccio ragionevole per piattaforme simili. –

+0

L'idea di Darrel potrebbe funzionare. HTTPS, quindi il cookie non può essere visto in transito. Richiederebbe qualche configurazione/modifica di JAAS sul lato server (JBoss) per cercare nel cookie se l'intestazione Autorizzazione non viene trovata. –

+0

Ok, ma non vuoi ancora le password e tali in un cookie se puoi evitarlo. Ciò che il cliente non conserva, non può perdere. –

0
  • dai browser di default non chiedere crendentials nuovamente quando si aggiorna una pagina. Potresti volerlo esaminare, perché se risolvi questo problema, il tuo problema verrà risolto.
  • È possibile mantenere un servizio REST per la maggior parte, tranne che l'utente può autenticarsi con HTTP o con un cookie. Cioè il servizio funziona anche se non si ha il cookie.

saluti,

Abby.

+0

Il browser richiede solo (e conserva) le credenziali quando riceve una risposta non autorizzata 401 e quindi inserisce la propria casella di login che vogliamo evitare. (Non possiamo evitarlo se inserisci la tua password in modo errato in primo luogo perché non possiamo intercettare quella risposta 401. Quindi quando digiti la tua password sbagliata, ottieni la casella di login del browser, e dopo di ciò il browser FAI ricorda le tue credenziali. (E si innesca per essere un patsy di CSRF ma questa è un'altra storia)) –

+0

@Mark: nella sicurezza basata su form, la pagina di accesso di solito non è protetta in modo da consentire l'autenticazione anonima e non genera 401 risposte. Stai facendo qualcosa di diverso qui? –

+0

@Steven: la pagina Web non è protetta (ad eccezione di HTTPS) e richiama XMLHttpRequest sul Servlet RESTful. –

0

Se si restituisce un ID sessione di qualche tipo dopo l'autenticazione e si è passati a ciascuna chiamata, questo non è molto diverso dal passare le credenziali di autenticazione con ogni chiamata. In termini di prestazioni, quest'ultimo può ancora memorizzare nella cache le credenziali, quindi non c'è alcun impatto sulle prestazioni. In termini di sicurezza, non è necessario mantenere le credenziali in giro, poiché le sessioni scadono ma le credenziali (di solito) no. Probabilmente, evitando le sessioni è più robusto, in quanto il server può dimenticare tutto tra le chiamate, ma funziona ancora.

In breve, non c'è argomento schiacciante in nessuna delle due direzioni e probabilmente non dovresti rimanere impigliato se sei sufficientemente "puro" nel tuo impegno per REST. Il vero problema è il comportamento del client, ed è qualcosa che puoi modificare indipendentemente da questo, come suggerisce Sjoerd.

+0

C'è una grande differenza nel fatto che una volta aperta la porta per memorizzare lo stato del client sul server diventa la strada più facile per archiviare ogni genere di cose. Ciò che è iniziato come un piccolo bit di stato di sessione, sta causando problemi di ridimensionamento e rende i client dipendenti da un particolare server di applicazioni. È un pendio scivoloso. –

+0

Dipende dal fatto che si tratti di dati o stato. Ad esempio, ho scritto un sistema che genera un profilo di sicurezza all'accesso e quindi lo memorizza nella cache. Questo dato non è stato perché può essere ricreato secondo necessità, anche se a un prezzo. In breve, se deve andare in una sessione, è lo stato, ma se può essere gettato in una cache, non lo è. –

+0

@Steven Non ho familiarità con quella distinzione tra dati e stato. Preferisco distinguere tra stato dell'applicazione client e stato risorsa. Lo stato delle risorse si può dare un URI e chiunque dovrebbe ottenere la stessa cosa se lo deniteri. Lo stato dell'applicazione client è specifico per un client. –