mercoledì 20 marzo 2013

RESTful applications in Spring MVC

Questo primo tutorial si occuperà di introdurre lo stile architetturale denominato REST e di presentarne una semplice implementazione usando Spring MVC.
Per comprendere al meglio questo tutorial è consigliabile avere una certa dimestichezza con il linguaggio Java e Spring framework, con le specifiche del protocollo HTTP e con il pattern Inversion of Control.

Cosa si intende per REST? L'acronimo sta per Representational State Transfer e si riferisce ad un paradigma architetturale con cui realizzare applicazioni web basate su HTTP. Le applicazioni web realizzate usando REST vengono chiamate RESTful.
Questo paradigma pone al centro di tutto le risorse. Cosa è una risorsa? Praticamente tutto è una risorsa! Qualunque informazione immagazzinata nel nostro database lo è, qualunque dato possediamo e desideriamo condividere. Nel paradigma REST le risorse sono identificate rigorosamente ed accedute mediante URI attraverso una unica astrazione o interfaccia uniforme: quella del protocollo HTTP. Ad esempio per fare un fetch di tutti gli ordinativi del nostro DB effettueremo una request di tipo:

GET /orders

Similmente, si useranno gli altri "metodi" tipici del protocollo HTTP:

- GET /orders/1  per selezionare l'ordine con id=1;
- POST /orders  per inserire un nuovo ordine;
- PUT /orders/1 per fare update dell'ordine avente id=1;
- DELETE /orders/1 per cancellare l'ordine avente id=1;
- GET /customers/1/orders per selezionare tutti gli ordini relativi al cliente con id=1;

Ovviamente le risorse possono essere di vario tipo, cioè avere diverse rappresentazioni (es. testo, un documento pdf, un'immagine, multimedia ecc.) anche se è consigliato utilizzare tipi standard per i quali esiste una vasta gamma di casi d'uso, rispetto ai tipi più "esotici".
Il tipo di risorsa viene specificato nella request header, mentre il tipo di rappresentazione in risposta viene mostrato nel Content-Type e questo lo vedremo bene nel codice.
La cosa interessante in tutto ciò è che il server non mantiene alcuna informazione di stato! In altri termini, il paradigma REST non usa la sessione. I client mantengono lo stato attraverso le chiamate, nel senso che le risorse vengono fornite già corredate di links (ovviamente provvisti dal server) così da garantire le transizioni di stato del client. Ad esempio, se l'ordine avente identificativo 109 è stato fatto dal cliente con id=12 e contiene gli oggetti con id 1200 e 1567, alla richiesta GET /orders/109 il server risponderà con qualcosa del tipo:

<order ref="/orders/109">
    <customer ref="/customers/12"/>
    <lineItems>
          <lineItem item="/catalog/item/1200" qty="2"/>
          <lineItem item="/catalog/item/1567" qty="8"/>
    </lineItems>
</order>

In cui si vede chiaramente che ogni risorsa è legata ad un URI che consente al client di ricostruire sempre le transizioni di stato. Da ciò si comprende come sia indispensabile, in fase di progettazione di una applicazione RESTful, una corretta definizione degli URI legati a tutte le risorse.
Se questo semplifica le cose in quanto disaccoppia drammaticamente il lato client dal lato server (con tutti i vantaggi legati ad un loose coupling come ad esempio la scalabilità), da un altro le complica per quanto riguarda la protezione delle risorse, ma questo problema della sicurezza lo affronteremo a suo tempo.

Nel prossimo post vi presenterò un esempio pratico completo di codice.



martedì 12 marzo 2013

Why Italian IT projects just suck

Questo post (o anche sfogo) avrebbe dovuto intitolarsi "why Italian IT projects and professionals just suck", poi un impeto di bontà mi ha fatto risparmiare le persone da quel giudizio forse troppo ingeneroso. Lo stimolo a scrivere qualcosa di simile mi proviene dai contatti quotidiani con colleghi che si dibattono in processi pseudo-industriali senza capo né coda che si lamentano continuamente della scarsa organizzazione nonché della scarsissima professionalità che è loro richiesta per portare avanti il lavoro.
Il problema principale risiede nella mia esperienza pluriennale nel campo, tanto come schiavo, analista programmatore, tanto con ruoli non meglio definiti ma che venivano, di volta in volta, rivestiti con un'etichetta posticcia. Questa andava da quelle credibili, tipo: "team leader", "project manager", a quelle assurdamente insignificanti come: "technology enthusiast" o "Spring evangelist" che sembrano sputate da un generatore casuale di qualifiche stronze. Inoltre ho avuto la fortuna di poter seguire anche progetti presso aziende extra nazionali ed ho potuto farmi un'idea, di sicuro parziale ed irrilevante, su quali possano essere le cause del fatto che qui da noi, la totalità dei progetti rappresenta un caso speciale a sé e costituisce un'emergenza sin dalle prime fasi della pianificazione. Si potrebbe, a questo punto, intavolare uno dei soliti discorsi-da-pausa-caffè in cui i consulenti (o lavoratori dell'IT) si producono nella tipica lamentela sul perché i progetti su cui lavorano facciano regolarmente tanto schifo o sul perché in Italia ci siano così tanto poche startup e perché negli USA ce ne siano così tante, anche fatte da italiani. In questi discorsi si cerca il capro espiatorio ponendolo di volta in volta in: motivazioni di budget, carenze del marketing, dirigenti stronzi e impreparati, notizie ruberie e tangenti prese - spesso a sproposito - da quei giornalini distribuiti gratuitamente nel metrò. Senza voler togliere veridicità a tutto ciò (potrebbe essere anche vero in tanti casi specifici), ci sarebbe da aggiungere una grande verità: i progetti IT in Italia fanno schifo perché fanno schifo i professionisti italiani dell'IT. Si tratta, in larga parte, di figure improvvisate che, cioè, non possiedono alcuna qualifica per svolgere il mestiere che fanno. E questo, si badi bene, partendo dalla base fino ad arrivare al top management. È come se pretendessi che un carpentiere che sa fare solo porte da interni faccia il ponte sullo Stretto di Messina.
Nel corso della mia carriera lavorativa si contano sulle dita di una mano le persone che, pur facendo gli analisti programmatori o i project manager ad esempio, avevano una qualche formazione (anche lontanamente) attinente a tale, non semplice, mestiere e che, particolare non trascurabile, venivano pagati in maniera commensurata al lavoro che svolgevano. Non so se sia per colpa della scuola che non fornisce formazione tecnica o della società o della crisi, o di personali inclinazioni, tuttavia è così. L'impreparazione e l'improvvisazione regnano sovrane.
Si badi bene: non è un corso di PMBOK a creare un ottimo project manager, così come non è un corso di Java a creare un buon programmatore! Chi sostiene il contrario o è in malafede o non ci ha capito granché. Ma questi sono punti di inizio imprescindibili per intraprendere quelle rispettive carriere e per sapere, anche lontanamente, di cosa si va a aparlare nella pratica lavorativa del quotidiano. Servono elementi quali la curiosità, l'entusiasmo, la giusta motivazione (anche economica!) per ciò che si va a fare. Queste "molle" diventano indispensabili in uno scenario in cui tutto cambia ed evolve a velocità pazzesche. Bisogna mettersi continuamente in discussione e con umiltà cercare di migliorare laddove si venga giudicati carenti. Ed eccoci al punto dolente. Chi ha le competenze per stabilire una metrica di giudizio professionale (basata ad esempio su obiettivi condivisi) sulla quale impiantare una seria valutazione meritocratica che spinga le persone a migliorare, motivandole? Insomma, il management è preparato a fare ciò? La risposta, anche in questo caso, è: assolutamente no. Ma qui da noi i problemi cominciano già dalle politiche di recruitment. Se infatti è comprensibile che ci siano delle difficoltà in campo HR (dovute essenzialmente alla jungla di burocrazie, leggi e normative caratteristiche del "Belpaese"), lo è assai di meno guardando le politiche di assunzione, specie nelle piccole e medie realtà. Qui infatti l'azienda ha la massima discrezionalità sulla scelta delle persone da assumere, e proprio in questo campo si vede l'assoluta incompetenza ed inefficienza nel saper distinguere le competenze di chi si candida. Quando invece, altrove nel mondo, si parla di recruitment basato sul social, sulle valutazioni fra peer ed è interessante come, ancora una volta, ci siano startup di italiani che propongono servizi all'avanguardia in tal senso (vedere questo Gild, ad esempio). Perché non possono farlo qui?
Forse la prendo alla larga.
Vi fidereste a farvi operare l'appendicite da un chirurgo che dichiarasse pubblicamente di operare sì, quando capita e per dovere, ma di trascorrete tutte le sue giornate, diciamo, giocando a tennis da tavolo? O facendo dolci moldavi? Siccome si è ciò che si fa più spesso, se la maggior parte del tuo tempo lo impieghi giocando a ping pong, sei prevalentemente un giocatore di ping pong. E, non so voi, ma io non mi farei operare da un giocatore di ping pong o da un pasticcere. Invece nell'IT italiano accade regolarmente questo: persone che sono tutt'altro dall'IT, pretendono di fare IT (fregando la propria azienda in primis) o vengono in qualche modo obbligate a farlo. A tutti i livelli. Se in Italia la prevalenza è delle piccole e medie imprese, dobbiamo concludere che forse (e sottolineo forse) l'attuale andamento dell'IT non consente alle piccole e medie realtà di fare bene il proprio lavoro. Le obbliga ad un complicato e continuo processo di arraffazzonamento e piccole cialtronerie per sbarcare il lunario e - comunque sempre - navigando a vista. Ad abbassare le tariffe ben al di sotto di punti critici, di fatto, uccidendo il mercato e, cosa ancora più grave, i professionisti. Infatti la sistematica applicazione di questo modo di procedere a tentoni e "al ribasso" ha prodotto l'uccisione di un'intera generazione di tecnici e professionisti che sono stati, di volta involta, assunti per ricorpire posizioni per cui erano incompetenti (e questo anche per colpa loro in quanto in Italia più che altrove ai colloqui si mente spudoratamente), poi sotto utilizzati, non adeguatamente motivati e formati, rilocati, riciclati, demoralizzati e regolarmente mobilitati quando non addirittura licenziati. Quali attività possono oggigiorno portarsi avanti con un tale materiale umano? Cosa si può fare "che funzioni" con questo retaggio? In verità, ben poco. Lo sa bene chi decide di costruire qualcosa di funzionante per vendere un servizio e deve pertanto garantire dei livelli soddisfacenti. Spesso è un serpente che si morde la coda ed è complicato spezzare questo circolo vizioso fatto di aziendine sempre in limine mortis, professionisti sfiduciati e costretti a lavorare con paghe da fame al proprio livello di incompetenza e che pertanto non sono in grado di trascinare le realtà in cui lavorano a quel livello di stabilità richiesto per poter investire su persone e tecnologie, che poi è l'ossatura delle aziende che stanno sul mercato internazionale (si fa prima a dire americano). In questo scenario la qualità dei prodotti è seriamente compromessa e, infatti, sono prodotti che non stanno in piedi, se non ad un costo umano esorbitante e con budget per la manutenzione che superano otto-dieci volte quello del progetto iniziale. Aggiustare tutto ciò in corsa? Possibile ma difficile.
Infatti lo scenario per il futuro non è roseo ed il business non aspetta che l'italietta di Collodi si organizzi coi suoi tempi. I grandi fornitori di servizi statunitensi si stanno dotando di infrastrutture che - da qui a cinque, dieci anni - gli consentiranno di evolvere verso nuove forme di servizio informatico che già si possono vedere in strumenti come le IaaS o le PaaS di Google, Amazon o VM Ware ed altre. Con la maturità delle tecnologie cosiddette "in cloud", l'IT vedrà ridurre ulteriormente il proprio perimetro di competenza e, conseguentemente, i propri budget. I servizi informatici somiglieranno sempre di più alla fornitura di corrente elettrica in una pubblica abitazione: plug & play. Si mette la spina nella presa, si consuma, si paga una bolletta. Il tutto ignorando ciò che c'è dietro, dove si trova e da chi è fatto. L'IT nel nostro Paese è quindi destinato a dissolversi. Al suo posto ci saranno le solite grandi multinazionali ed in più nasceranno piccole ed agili società di brokers che come lavoro andranno porta a porta nelle aziende a "piazzare" servizi che vengono fatti dai professionisti americani a Mountain View o da qualche parte in India. Questi piazzisti dell'IT saranno probabilmente quelli che oggi lavorano come programmatori junior (sottopagati) in uno dei grandi carrozzoni del nostro Paese, con buona pace di quelli che si riempiono la bocca con parole di aiuto ai "giovani". Il lato positivo è che Italian IT projects & professional won't suck anymore because you cannot suck if you don't exist.

lunedì 4 marzo 2013

README.txt

Ciao a tutti. Questo è il classico post di benvenuto che non legge nessuno.
Tuttavia, ci tengo a specificare alcune cosette sui contenuti che, di volta in volta, pubblicherò qui.
Sono un appassionato di IT e di tecnologie in genere, quello che nel mondo anglosassone si definisce (più o meno scherzosamente) un geek. Durante la mia vita ho risolto una cifra di problemi lavorativi legati a tecnologie, linguaggi e così via. Ho sempre considerato il web come una fonte inesauribile di tips, credendo fermamente che Google sia il miglior amico di chi lavora in questo campo. Perché, per ogni problema, c'è sempre qualcuno che l'ha già avuto e che ha pensato ad una soluzione prima di te. Il senso della community è solidarietà e questa è spesso la chiave di tutto. Ho sempre usato il lavoro degli altri per risolvere il mio, ma non ho mai avuto il tempo di condividere il risultato con altri, se non per passaparola.
Questo blog nasce perché "non è mai troppo tardi".
Pertanto, il codice e, in generale, tutto ciò che troverete nei miei post è di mia proprietà (salvo laddove altrimenti specificato), tuttavia sentitevi liberi di usarlo come più vi aggrada. Vi sarei grato se però lo faceste in rispetto alla Licenza Creative Commons che ho scelto per i contenuti e di mandarmi una mail per altri utilizzi che non fossero previsti dalla suddetta licenza.
Vi prego anche di inviarmi le vostre idee, consigli, critiche e quant'altro.
Spero che questo posto possa essere di aiuto a quante più persone possibile.
Se poi a qualcuno di voi interessa chi sono più in dettaglio, può andarselo a vedere nella pagina Bio e divertirsi un po'.
Cheerzzz

OAuth2: questo sconosciuto (per me)

Logo del progetto OAuth
Sebbene la specifica di OAuth2 sia ancora tutt'altro che priva di ambiguità, ci sono un sacco di servizi che già ne utilizzano svariate implementazioni (spesso arbitrarie). Tuttavia, se sui princìpi di funzionamento si trovano parecchi contributi esplicativi (ovviamente in lingua inglese), sulla implementazione al di fuori di contesti standardizzati c'è ben poco. Per non parlare di quando si cercano pezzi di codice funzionante, ad esempio, per applicazioni RESTful sotto Spring framework.
Recentemente mi è capitato di dover sviluppare una tale implementazione e, quindi, di dover combattere con la configurazione di OAuth2 per Spring e con la spesso astrusa orchestrazione delle varie request e redirects che la caratterizzano. Per di più mi sono trovato ad operare in un contesto di persistenza NoSQL (MongoDB). Non è stato per niente facile venirne fuori, il che mi ha fatto sentire spesso abbastanza scemo(frustrating). In questo ed in successivi post, mi riprometto pertanto di chiarire alcuni concetti ambigui di OAuth2 e di presentarvi un esempio funzionante from scratch di come implementare OAuth2 utilizzando Spring framework e Mongo Db. Vi mostrerò poi come ho utilizzato l'utility cURL per testare il tutto. Una serie di post molto interessanti sull'argomento (e da cui ho tratto spunto in più di una occasione) potete trovarli su questo blog http://techblog.hybris.com/. Il codice utilizzato, invece, potete trovarlo pubblicato nel mio spazio Github.

OAuth2: perché farsi del male?
La specifica di OAuth2, per quanto noiosa, andrebbe letta da cima a fondo. Come ogni documento architetturale ben fatto, questo paper (sebbene non sia perfetto) non solo chiarisce i dettagli del funzionamento del protocollo nei vari scenari possibili, ma soprattutto definisce in maniera univoca gli attori, i ruoli e le motivazioni che hanno spinto alla formalizzazione della specifica stessa. In questa sede non ci interessa entrare in tali dettagli, quanto piuttosto riassumerne i punti chiave per permettere a chi si trova nella condizione di dover implementare il protocollo in un contesto applicativo di comprenderne il funzionamento e di risolvere eventuali problemi che dovessero presentarsi.
Innanzitutto perché OAuth2? Diciamo subito che non esiste un'unica ragione. Nella specifica si punta il dito sulle limitazioni del tradizionale modello client-server quando un resource-owner (ossia una entità che possiede dei dati ad accesso controllato) voglia condividere ad applicazioni di terze parti l'accesso alle proprie risorse. Normalmente ciò implica la condivisione di una password, sebbene sia chiaro che questo non sia esattamente il metodo più sicuro di proteggere i dati. In secondo luogo poi, il resource-owner non ha alcun modo per limitare l'accesso ad un solo sottoinsieme di dati o restringerne la durata nel tempo. Inoltre, l'unico modo che ha di impedire che una certa applicazione acceda alle risorse è quello di cambiare la password, il che inibisce l'accesso a tutti i client. Infine, l'intero sistema risulta vulnerabile in quanto basta che una sola delle applicazioni client sia poco sicura per compromettere la sicurezza dei dati e di tutte le altre applicazioni. OAuth2 fa in modo di disaccoppiare il ruolo del client da quello del resource owner ed introduce fra i due un authorization server. Ciò fa in modo che il client ottenga delle credenziali di accesso ai dati che sono diverse da quelle offerte dal resource owner. Ciò che accade è che il client ottiene dall'authorization server un access token, cioè una stringa che contiene attributi che definiscono lo scope, la durata ed altre modalità di accesso ai dati. Una volta ottenuto il token, il client lo usa per accedere ai dati senza ulteriori filtri con le modalità definite dal token stesso.
Nella figura sottostante (presa direttamente dalla specifica) si mostra il flusso astratto del protocollo OAuth2.

     +--------+                               +---------------+
     |        |--(1)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(2)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(3)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(4)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(5)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(6)--- Protected Resource ---|               |
     +--------+                               +---------------+

                     Abstract Protocol Flow


Come si vede, sono previsti i seguenti step:

  1. Il client richiede l'autorizzazione dal resource owner;
  2. Il client riceve dal resource owner un authorization grant che rappresenta l'autorizzazione del resource owner. La specifica definisce quattro grant possibili: authorization code, implicit, resource owner password credentials e client credentials. Ci soffermeremo sulla natura di questi grants nelle singole implementazioni. Per il momento basti sapere che l'authorization grant dipende dalle modalità usate dal client per richiedere l'autorizzazione e dai tipi di autorizzazione supportati dall'authorization server.
  3. Il client usa l'authorization grant ottenuto nello step precedente per richiedere un access token all'authorization server.
  4. L'authorization server autentica il client, valida l'authorization grant e, se valido, rilascia un access token.
  5. Il client richiede la risorsa al resource server presentando l'access token.
  6. Il resource server valida il token e, se valido, serve le risorse richieste.
C'è da dire che questo è un flusso astratto nel senso che mette in evidenza tutti i ruoli previsti dalla specifica. Tuttavia, nei vari flussi possibili, come si vedrà nel seguito, tali ruoli possono essere accorpati in singoli attori o rimanere separati ed essere svolti da entità logicamente diverse. Ad esempio, si vedrà che il client utilizza l'authorization server come intermediario verso il resource owner per ottenere l'authorization grant.


Un solo protocollo, quattro flussi
Perché OAuth2, a fronte di un unico flusso astratto, prevede ben quattro possibili implementazioni per i flussi di utilizzo? Una possibile ragione sta nel fatto che oggi, più che mai in passato, esistono svariate tipologie di applicazioni e di client. Vi basti pensare al boom dei dispositivi mobile per farvi un'idea. Alcuni dei flussi previsti dalla specifica si addicono maggiormente ad applicazioni web server-side "classiche", altri vanno meglio nel caso si abbiano dei client mobile altri ancora si prestano ad utilizzi misti e mirabolanti. Ovviamente, nessuno obbliga gli sviluppatori e le aziende ad utilizzare implementazioni di OAuth2 già esistenti (come quella di Spring cui accennavo prima, o anche CXF della Apache Software Foundation). In linea di principio è possibile sviluppare una propria implementazione partendo direttamente dalle specifiche (dotandosi di una buona dose di caffeina, per non dire altro). Tuttavia una cosa simile la si farebbe a rischio e pericolo della organizzazione per cui si lavora e dei suoi utenti. Perché, e non dimentichiamolo mai, la ragione principale per cui è nato OAuth risiede nella sicurezza dei dati che tramite API si intendono esporre ai client. Una implementazione non standard della specifica (e quindi non certificata) potrebbe essere buggata, essere poco affidabile e facilmente forzata da utenti malintenzionati. Le implementazioni standard invece sono spesso soggette ad un'accurata analisi delle communities, continuamente testate e debuggate. Insomma, perché rischiare?
Vediamo quindi questi quattro flussi standard.
  1. Authorization Code Flow. Questo flusso è spesso indicato come il "tipico flusso OAuth2" ed è quello più indicato per le web applications server-side. In questo flusso, l'applicazione client viene redirezionata all'authorization endpoint del provider (ossia dell'attore che detiene le risorse). Qui avviene una autenticazione in due step. Nel primo step, l'utente, se non è già loggato (ossia se non dispone di un sessionId valido) deve fare un vero e proprio login con username e password. Nel secondo step, l'utente dovrà garantire l'accesso ai dati al particolare client.Questo è quanto avviene, ad esempio, quando create un nuovo account Twitter e vi viene chiesto di accedere ad i vostri contatti GMail per vedere quali fra questi dispone già di un account. Se non siete loggati a GMail, vi verrà chiesto di farlo e, successivamente, GMail vi chiederà qualcosa tipo: "volete permettere che l'applicazione Twitter acceda ai vostri dati?". Se accettate, opportunamente informati con appositi disclaimer e quindi pienamente consapevoli dei rischi, allora il flusso prosegue allo step successivo. Questo consiste in un redirect al client in cui il provider invia un codice (che in seguito potrà essere scambiato con un access token vero e proprio) ed un altro parametro di "stato", con funzioni di controllo sulla validità della sessione e sul cui utilizzo ci soffermeremo nel seguito. Nel prossimo step, il client invia il codice appena ricevuto e richiede al server un authorization token. A questa request, il provider risponde con l'authorization token vero e proprio, assieme ad altre informazioni come il periodo di validità del token espresso in ore ed un refresh token che serve a rinnovare un eventuale token scaduto senza dover rifare tutta la trafila.
  2. Flusso Implicito (Client-Side Flow). Questo flusso è più snello rispetto al precedente, ed è anche meno sicuro. Esso è però necessario laddove il client non abbia modo di poter conservare un token o un secret. Siamo cioè nel caso, ad esempio, di applicazioni che si riducono al codice JavaScript che viene interpretato in un browser. È evidente, in questo scenario, che il client non ha modo di poter conservare un segreto in maniera affidabile. Per questo tipo di applicazioni, tipicamente, non vi fidereste mai di rilasciare un token la cui validità è di giorni, quanto piuttosto di poche, pochissime ore! Questo perché voi, lato server, NON potrete mai sapere quanto bene sia stata realizzata l'applicazione dei client. Quanto sia resistente, ad esempio, ad attacchi tipo XSS (Cross-Site Scripting) che possano sottrarre il token. Non parliamo poi di dare al client addirittura la possibilità di fare il refresh di un token scaduto! In un tale contesto, il flusso precedente, con tutti i suoi scambi di codici e refresh token, diventa inutile e ridondante (oltre che potenzialmente pericoloso). Per questi client si adotta allora il flusso implicito. In cosa consiste? Dire "implicito" è come dire "sottinteso". Cosa esattamente è sottinteso in questo flusso rispetto al precedente? È presto detto: a differenza del precedente, in questo flusso il token viene fornito al client senza alcuna richiesta esplicita. Pertanto questa volta il client invia meno parametri al server (vedremo i dettagli in seguito) in quanto non è richiesta l'autenticazione del client. Anziché ritornare un authorization code, il server ritorna direttamente il token di accesso, nel fragment #hash dell'URI. A questo punto, il resto della logica avviene nel JavaScript all'interno del browser del client, che pertanto in questo flusso svolge il ruolo di user agent. Questo esegue una redirect al server senza inviare il fragment contenente il token. Il server, a questo punto, risponde con una pagina HTML5 in cui c'è il link ad una libreria JavaScript che consente allo user agent, cioè al browser, di estrarre l'access token dal fragment #hash. Il client adesso dispone del token per accedere alle risorse del provider.
  3. Resource Owner Password Flow. Su questo flusso è stato difficilissimo reperire dettagli implementativi. Per fare questa ricostruzione mi sono pertanto basato su poche fonti, tuttavia, all'atto pratico, l'implementazione sembra funzionare. Anche qui sono ben accette correzioni e contributi da parte di chi abbia una versione funzionante di questo flusso e desideri condividerla. Questo flusso è per parecchi versi molto semplice. Il client fornisce le sue credenziali e riceve in cambio un access token ed un refresh token. Si noti esplicitamente che questi sono forniti assieme. A questo punto qualcuno che ha seguito meglio storcerà il naso. Come mai facciamo tanto per implementare OAuth e non dare le credenziali all'applicazione client e qui invece le inseriamo? Questa è una giusta osservazione e infatti nella specifica si dice chiaramente che questo flusso è da implementare quando si abbia una applicazione client che è a tutti gli effetti trusted. L'esempio tipico è quello dell'applicazione ufficiale di Spotify che accede al vostro db musicale. In questo caso voi, gli utenti di Spotify, siete i resource owner e accedete ai vostri dati, ospitati da Spotify, mediante l'applicazione ufficiale di Spotify. È ovvio che in questo scenario l'applicazione è fidata ed è l'unica che accede e quindi può bene accettare le credenziali in luogo del token. Da questa osservazione si capisce anche come mai, congiuntamente all'access token, venga anche fornito il refresh token. Infatti, se così non fosse, alla scadenza dell'access token, delle due una: o sarebbe richiesto nuovamente di inserire le credenziali o il client in qualche modo deve ricordarsele, cioè memorizzarle da qualche parte, con notevoli implicazioni dal punto di vista della sicurezza. Ciò detto, da un punto di vista funzionale, il flusso è molto semplice. Il client chiederà subito le credenziali e l'utente dovrà inserirle direttamente nell'applicazione. A questo punto è necessario che l'utente sia certo che l'applicazione client sia davvero quella ufficiale. Deve cioè scaricarla dal sito ufficiale, da un app store fidato, avere un certificato o un hash o un qualunque altro metodo. L'importante è che sia certo di potersi fidare dell'applicazione client e di potervi inserire le credenziali. A questo punto, l'app client fa una request all'authorization server inviando (nello header della request o, in alternativa, nel body) client_id, client_secret (trattate come username e password), le credenziali vere e proprie dell'utente, un grant_type settato al valore 'password' e la dicitura "Authorization:Basic" che dice all'authorization server di eseguire un'autorizzazione solo sulla base delle credenziali del client. A questo punto l'auth server risponderà inviando access token e refresh token e il client non avrà più bisogno di inserire le credenziali per accedere alle risorse protette.
  4. Client Credentials Flow. Questo flusso è assai simile al precedente e ricalca il "Two-Legged Flow" presente nella specifica OAuth1. In sostanza il flusso consiste di una singola request e response come il precedente. Solo che in questo caso si inviano solo client_id e client_secret. L'authorization server risponderà direttamente fornendo l'access token ma non in refresh token. Ciò implica che, allo scadere dell'access token, il client dovrà semplicemente richiederne uno nuovo fornendo client_id e client_secret.

Per quanto riguarda la descrizione del funzionamento di OAuth2, è tutto qui. Dal prossimo post cominceremo a vedere una prima implementazione. Ovviamente se ci sono osservazioni, correzioni o richieste di ulteriori precisazioni, vi prego di farlo attraverso i commenti o, se preferite, contattandomi privatamente.
Alla prossima!