cos’è il Cross-Origin Resource Sharing? un meccanismo che consente ad una applicazione web di accedere a risorse di un altro dominio.

 

Perché serve? per una serie di motivi tutti molto validi ed attuali:

  1. perché con l’uso intensivo di librerie javascript che fanno chiamate AJAX e l’esplosione di social network che consentono di accedere alle proprie risorse, le applicazioni web sono diventate vere e proprie “rich client application”, in grado di richiamare un’elevata serie di funzionalità e dati da fonti esterne
  2. per questioni di sicurezza. Infatti tutti i browser implementano una policy che impedisce alle applicazioni web di accedere a risorse esterne se non rispettando determinate caratteristiche (same-origin policy).

 

Perché ne parlo? perché mi è servito per realizzare un ambiente di User Acceptance Test completamente gratuito! (venale, ma è la verità). Scherzi a parte, mi ero prefissato l’obiettivo di rimanere low-cost e dopo un po’ è diventato quasi una sfida personale. Infatti nel mondo .NET non sono molti i provider che consentono di avere server senza costi di attivazione o canoni (su questo fronte i colleghi del PHP hanno una vita più facile).

Quello che ho trovato io è Somee.com: per ambienti piccoli o di test mette a disposizione Server Windows 2012 (ad oggi) con SQL Server senza dover sostenere alcun costo. L’interfaccia di gestione è un po’ spartana, ma con il solito accesso FTP alla fine si riesce a fare quello che serve.

Bello! Se non fosse che Somee.com impone di visualizzare sulle pagine HTML restituite dai loro server gratuiti un po’  di pubblicità. Non sono contrario a questo baratto (a caval donato non si guarda in bocca). Il problema sta nel modo in cui inseriscono questa pubblicità…infatti hanno fatto in modo che ogni risorsa html richiesta al server venga restituita con il seguente suffisso:

<!--SCRIPT GENERATED BY SERVER! PLEASE REMOVE-->
<center><a href="http://somee.com">Web hosting by Somee.com</a></center>
</textarea></xml>< /script></noframes></noscript></object></layer></style></title></applet>
<script language="JavaScript" src="http://ads.mgmt.somee.com/serveimages/ad2/WholeInsert4.js">< /script>
<!--SCRIPT GENERATED BY SERVER! PLEASE REMOVE-->

questo “giochino” ha lo spiacevole effetto di spaccare completamente la mia applicazione angular.js!!!

Infatti tutte le direttive richiedono che il proprio template abbia un root-node unico…cosa che, con somee.com, non è più vera…

Non mi sono rassegnato alla cosa (anche perché, da newbie, deployare per la prima volta l’applicazione su questi server, mi è costato diverse ore) ed ho ripensato a quanto accennato in un precedente articolo, ovvero che, grazie all’organizzazione dei servizi e all’uso di una baseUrl unica, è molto semplice indicare ad Angular quale server puntare per le chiamate RESTful. BENE!

Grazie a Github (che non finirò mai di ringraziare!) chiunque si registri ha a disposizione (gratuitamente) uno spazio web per la pubblicazione del proprio materiale: Github Pages, che è, per l’appunto, lo spazio in cui pubblico questi articoli. A questo punto credo di aver tutto e potrei realizzare il mio ambiente di UAT con questo Environment Management:

 

Ogni Client quindi interroga il server Github per le risorse statiche (.html, .js, .css, ecc.) ed il server Somee per le risorse dinamiche (i servizi). In questo scenario, il client deve poter fare chiamate CORS e le web api devono essere configurate per consentire l’accesso dall’esterno. Considerando questo scenario, vorrei anche prevedere che l’origine autorizzata sia configurabile e annullabile (perché in produzione avrei origini differenti o potrei non avere affatto bisogno di questo scenario).

 

Per far questo i passaggi sono stati semplici:

  1. installazione della libreria Microsoft.Owin.Cors
  2. Creazione di una sezione applicativa di configurazione del CORS
  3. Creazione di una classe di CORS Policy custom (con l’origine da abilitare)
  4. Impostazione della policy CORS in funzione dei dati in configurazione

Funziona. Ed è gratis!  

Preflighted requests

Interessante è stato vedere all’opera le preflighted requests, che sono uno dei comportamenti della policy CORS che i browser applicano. Consiste nel fatto che il browser, a fronte di caratteristiche particolari (ad es. per la presenza di header custom), sempre per garantire la sicurezza, prima di eseguire una richiesta http Cross-Origin, “bussa” al server con una richiesta light, con header di base e method OPTIONS, per assicurarsi che questa chiamata sia riconoscibile dal server.

Nell’ambiente di UAT di Discitur, è molto evidente questo comportamento, infatti, a seguito dell’autenticazione, grazie all’uso degli interceptor Angular.js si inserisce un header custom con il token di autenticazione. Questo ulteriore token mette in allerta il browser, che avvia il meccanismo delle preflighted requests

Se si verifica il traffico dell’applicazione, si può vedere che prima dell’autenticazione si hanno simple requests:

con abilitazione al CORS

dopo l’autenticazione, con il token nell’head, il browser lancia le preflight requests:

ognuna delle quali “bussa” al server richiedendo l’autorizzazione alla chiamata reale:

Articoli indispensabili sul tema sono:
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api  

Comments