CORS in JAX-RS

1. Panoramica

In questo rapido articolo, impareremo come abilitare CORS ( Cross-Origin Resource Sharing ) in un sistema basato su JAX-RS . Configureremo un'applicazione su JAX-RS per abilitare il meccanismo CORS .

2. Come abilitare il meccanismo CORS

Ci sono due modi in cui possiamo abilitare CORS in JAX-RS. Il primo e il modo più semplice è creare un filtro per iniettare l'intestazione della risposta necessaria in fase di esecuzione in ogni richiesta. L'altro consiste nell'aggiungere manualmente un'intestazione appropriata in ogni endpoint URL.

Idealmente, dovrebbe essere utilizzata la prima soluzione; tuttavia, quando questa non è un'opzione, l'opzione più manuale è anche tecnica OK.

2.1. Utilizzo del filtro

JAX-RS ha l' interfaccia ContainerResponseFilter , implementata dai filtri di risposta del contenitore. In genere, questa istanza di filtro viene applicata globalmente a qualsiasi risposta HTTP.

Implementeremo questa interfaccia per creare un filtro personalizzato che inietterà l' intestazione Access-Control-Allow- * a ciascuna richiesta in uscita e abiliterà il meccanismo CORS :

@Provider public class CorsFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { responseContext.getHeaders().add( "Access-Control-Allow-Origin", "*"); responseContext.getHeaders().add( "Access-Control-Allow-Credentials", "true"); responseContext.getHeaders().add( "Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); responseContext.getHeaders().add( "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); } }

Un paio di punti qui:

  • I filtri che implementano ContainerResponseFilter devono essere annotati esplicitamente con @Provider per essere rilevati dal runtime JAX-RS
  • Stiamo inserendo l'intestazione " Access-Control-Allow- * " con "*", il che significa che è possibile accedere a qualsiasi endpoint URL di questa istanza del server tramite qualsiasi dominio; se vogliamo limitare esplicitamente l'accesso interdominio, dobbiamo menzionare quel dominio in questa intestazione

2.2. Utilizzo della modifica dell'intestazione in ogni endpoint

Come affermato in precedenza, possiamo inserire esplicitamente l' intestazione " Access-Control-Allow- * " anche a livello di endpoint:

@GET @Path("/") @Produces({MediaType.TEXT_PLAIN}) public Response index() { return Response .status(200) .header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Credentials", "true") .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization") .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD") .entity("") .build(); }

Un punto da notare qui è che se stiamo cercando di abilitare CORS in un'applicazione di grandi dimensioni, non dovremmo provare questo metodo perché in questo caso, dobbiamo iniettare manualmente l'intestazione in ogni endpoint URL che introdurrà un sovraccarico aggiuntivo.

Tuttavia, questa tecnica può essere utilizzata nelle applicazioni, dove è necessario abilitare CORS solo in alcuni degli endpoint URL.

3. Test

Una volta che l'applicazione è attiva, possiamo testare le intestazioni usando i comandi curl. L'output di un'intestazione di esempio dovrebbe essere simile al seguente:

HTTP/1.1 200 OK Date : Tue, 13 May 2014 12:30:00 GMT Connection : keep-alive Access-Control-Allow-Origin : * Access-Control-Allow-Credentials : true Access-Control-Allow-Headers : origin, content-type, accept, authorization Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS, HEAD Transfer-Encoding : chunked

Inoltre, possiamo creare una semplice funzione AJAX e controllare la funzionalità interdominio:

function call(url, type, data) { var request = $.ajax({ url: url, method: "GET", data: (data) ? JSON.stringify(data) : "", dataType: type }); request.done(function(resp) { console.log(resp); }); request.fail(function(jqXHR, textStatus) { console.log("Request failed: " + textStatus); }); };

Ovviamente per eseguire effettivamente il controllo, dovremo eseguirlo su un'origine diversa rispetto all'API che stiamo utilizzando.

Puoi farlo localmente abbastanza facilmente eseguendo un'app client su una porta separata, poiché la porta determina l'origine.

4. Conclusione

In questo articolo, abbiamo mostrato l'implementazione del meccanismo CORS nelle applicazioni basate su JAX-RS.

Come sempre, il codice sorgente completo è disponibile su GitHub.