Creazione di un'API per applicazioni mobili - Autenticazione e autorizzazione


Answers

Sono un sacco di domande in una, credo che molte persone non siano riuscite a leggere fino alla fine :)

La mia esperienza nell'autenticazione dei servizi Web è che la gente di solito la ridefinisce e i problemi sono gli stessi che si incontrerebbero su una pagina web. Possibili opzioni molto semplici includerebbero https per il passo di accesso, restituire un token, richiedere che fosse incluso nelle richieste future. È anche possibile utilizzare l'autenticazione di base http e passare semplicemente i dati nell'intestazione. Per maggiore sicurezza, ruotare / espirare i token frequentemente, controllare che le richieste provengano dallo stesso blocco IP (questo potrebbe diventare complicato anche se gli utenti mobili si spostano tra le celle), combinandosi con la chiave API o simile. In alternativa, esegui il passaggio "request key" di oauth (qualcuno lo ha già suggerito in una risposta precedente ed è una buona idea) prima di autenticare l'utente e usarlo come chiave richiesta per generare il token di accesso.

Un'alternativa che non ho ancora usato, ma ne ho sentito parlare molto in quanto un'alternativa "friendly" ai dispositivi oAuth è xAuth . Dai un'occhiata e se lo usi allora sarei davvero interessato a sapere quali sono le tue impressioni.

Per l'hashing, sha1 è un po 'meglio ma non si blocca - qualunque cosa i dispositivi possano facilmente implementare (e rapidamente in termini di prestazioni) probabilmente va bene.

Spero che ti aiuti, buona fortuna :)

Question

Panoramica

Sto cercando di creare un'API (REST) ​​per la mia applicazione. Lo scopo iniziale / primario sarà il consumo da parte delle app mobili (iPhone, Android, Symbian, ecc.). Ho esaminato diversi meccanismi per l'autenticazione e l'autorizzazione per le API basate sul Web (studiando altre implementazioni). Ho la testa contorta sulla maggior parte dei concetti fondamentali, ma sto ancora cercando indicazioni in alcune aree. L'ultima cosa che voglio fare è reinventare la ruota, ma non sto trovando alcuna soluzione standard che si adatta ai miei criteri (tuttavia i miei criteri sono errati e quindi mi sento libero di criticare anche questo). Inoltre, voglio che l'API sia la stessa per tutte le piattaforme / applicazioni che la consumano.

oAuth

Vado avanti e butto la mia obiezione a oAuth poiché so che probabilmente sarà la prima soluzione offerta. Per le applicazioni mobili (o più specificamente le applicazioni non web), sembra sbagliato lasciare l'applicazione (per andare a un browser Web) per l'autenticazione. Inoltre, non è possibile (sono a conoscenza) che il browser restituisca il callback all'applicazione (in particolare la multipiattaforma). Conosco un paio di app che lo fanno, ma è semplicemente sbagliato e dà un'interruzione nell'applicazione UX.

Requisiti

  1. L'utente immette nome utente / password nell'applicazione.
  2. Ogni chiamata API viene identificata dall'applicazione chiamante.
  3. L'overhead è ridotto al minimo e l'aspetto auth è intuitivo per gli sviluppatori.
  4. Il meccanismo è sicuro sia per l'utente finale (le sue credenziali di accesso non sono esposte) sia per lo sviluppatore (le credenziali dell'applicazione non sono esposte).
  5. Se possibile, non richiedere https (in nessun caso un requisito severo).

I miei pensieri correnti sull'implementazione

Uno sviluppatore esterno richiederà un account API. Riceveranno un apikey e apisecret. Ogni richiesta richiederà almeno tre parametri.

  • apikey: assegnato allo sviluppatore alla regisrazione
  • timestamp - raddoppia come identificativo univoco per ogni messaggio per un determinato apikey
  • hash - un hash del timestamp + l'apisecret

L'apikey è necessario per identificare l'applicazione che ha emesso la richiesta. Il timestamp agisce in modo simile a oauth_nonce ed evita / attenua gli attacchi di replay. L'hash garantisce che la richiesta sia stata effettivamente emessa dal proprietario della data chiave.

Per le richieste autenticate (quelle fatte per conto di un utente), sono ancora indeciso tra l'andare con una route access_token o una combinazione di hash username e password. In ogni caso, a un certo punto sarà richiesta una combinazione di nome utente / password. Quindi, quando lo fa, un hash di diverse informazioni (apikey, apisecret, timestamp) + verrebbe utilizzata. Mi piacerebbe un feedback su questo aspetto. Cordiali saluti, avrebbero dovuto hash prima la password, dal momento che non memorizzo le password nel mio sistema senza hash.

Conclusione

Cordiali saluti, questa non è una richiesta su come costruire / strutturare l'API in generale solo come gestire l'autenticazione e l'autorizzazione esclusivamente all'interno di un'applicazione.

Pensieri casuali / Domande bonus

Per le API che richiedono solo un apikey come parte della richiesta, come impedire a qualcuno che non sia il proprietario di apikey di vedere l'apikey (poiché inviato in chiaro) e fare richieste eccessive per spingerli oltre i limiti di utilizzo? Forse sto solo pensando a questo, ma non dovrebbe esserci qualcosa per autenticare che una richiesta è stata verificata al proprietario di apikey? Nel mio caso, questo era lo scopo dell'apisecret, non viene mai mostrato / trasmesso senza essere sottoposto a hash.

A proposito di hash, che dire di md5 contro hmac-sha1? Ha davvero importanza quando tutti i valori sono sottoposti a hash con dati sufficientemente lunghi (ad esempio apisecret)?

In precedenza avevo pensato di aggiungere un hash per utente / riga salt all'hash della password dei miei utenti. Se dovessi farlo, come potrebbe l'applicazione essere in grado di creare un hash corrispondente senza conoscere il sale utilizzato?




Quindi quello che cerchi è una sorta di meccanismo di autenticazione lato server che gestirà gli aspetti di autenticazione e autorizzazione di un'applicazione mobile?

Supponendo che questo sia il caso, allora mi piacerebbe affrontarlo come segue (ma solo perche 'sono uno sviluppatore Java quindi un C # guy lo farebbe diversamente):

Il servizio di autenticazione e autorizzazione RESTful

  1. Funzionerà solo su HTTPS per impedire intercettazioni.
  2. Sarà basato su una combinazione di RESTEasy , Spring Security e CAS (per Single Sign-On su più applicazioni).
  3. Funzionerà con entrambi i browser e le applicazioni client abilitate al web
  4. Ci sarà un'interfaccia di gestione degli account basata sul web per consentire agli utenti di modificare i loro dettagli, e gli amministratori (per particolari applicazioni) di modificare i livelli di autorizzazione

La libreria / applicazione di sicurezza lato client

  1. Per ogni piattaforma supportata (es. Symbian, Android, iOS ecc.) Creare un'adeguata implementazione della libreria di sicurezza nella lingua nativa della piattaforma (ad es. Java, ObjectiveC, C ecc)
  2. La libreria deve gestire la formazione delle richieste HTTPS utilizzando le API disponibili per la piattaforma indicata (ad esempio, Java utilizza URLConnection, ecc.)
  3. I consumatori della libreria di autenticazione e autorizzazione generale ('cos che è tutto ciò che è) codificheranno su un'interfaccia specifica e non saranno felici se cambierà così assicuratevi che sia molto flessibile. Segui le scelte progettuali esistenti come Spring Security.

Quindi ora che la vista da 30.000 piedi è completa, come si fa a farlo? Bene, non è così difficile creare un sistema di autenticazione e autorizzazione basato sulle tecnologie elencate sul lato server con un client browser. In combinazione con HTTPS, i framework forniranno un processo sicuro basato su un token condiviso (solitamente presentato come cookie) generato dal processo di autenticazione e utilizzato ogni volta che l'utente desidera fare qualcosa. Questo token viene presentato dal client al server ogni volta che viene effettuata una richiesta.

Nel caso dell'applicazione mobile locale, sembra che tu stia cercando una soluzione che faccia quanto segue:

  1. L'applicazione client ha un elenco di controllo di accesso (ACL) definito che controlla l'accesso di runtime alle chiamate di metodo. Ad esempio, un determinato utente può leggere una raccolta da un metodo, ma il loro ACL consente solo l'accesso agli oggetti che hanno una Q nel loro nome, quindi alcuni dati nella raccolta vengono tirati in basso dall'interceptor di sicurezza. In Java questo è semplice, basta usare le annotazioni Spring Security sul codice chiamante e implementare un processo di risposta ACL adatto. In altre lingue, sei da solo e probabilmente dovrai fornire il codice di sicurezza che può essere chiamato nella tua libreria di sicurezza. Se il linguaggio supporta AOP (Aspect Oriented Programming), utilizzalo al meglio per questa situazione.
  2. La libreria di sicurezza memorizza nella cache l'elenco completo delle autorizzazioni nella memoria privata per l'applicazione corrente in modo che non debba rimanere connesso. A seconda della durata della sessione di accesso, questa potrebbe essere un'operazione singola che non verrà mai ripetuta.

Qualunque cosa tu faccia, non provare a inventare il tuo protocollo di sicurezza , o usare la sicurezza per oscurità. Non sarai mai in grado di scrivere un algoritmo migliore per questo rispetto a quelli che sono attualmente disponibili e gratuiti. Inoltre, le persone si fidano di algoritmi ben noti. Pertanto, se affermi che la tua libreria di sicurezza fornisce l'autorizzazione e l'autenticazione per le applicazioni mobili locali utilizzando una combinazione di token crittografati SSL, HTTPS, SpringSecurity e AES, avrai immediatamente credito nel mercato.

Spero che questo aiuti, e buona fortuna con la vostra impresa. Se desideri maggiori informazioni, fammi sapere - Ho scritto un bel po 'di applicazioni web basate su Spring Security, ACL e simili.




Related