maggio 22, 2017

Controllo dell’autenticazione con Spring MVC e Handler Interceptor

Nel contesto di un’applicazione web Spring MVC, l’oggetto HandlerInterceptor sostituisce il concetto del tradizionale Servlet Filter J2EE. Il suo scopo è quello di rimanere in ascolto e intercettare tutte le URL mappate sull’applicazione e processate da un Handler. In termini di programmazione event-driven, gli Handler sono dei gestori di eventi che vengono richiamati per gestire e rispondere ad un determinato evento come può essere per esempio un processo d’invocazione Request-Response di un servizio web. L’oggetto HandlerInterceptor si inserisce nel ciclo di vita di un Handler ed è in grado di effettuare delle operazioni indipendenti e in maniera completamente disaccoppiata da esso. HandlerInterceptor definisce tre metodi per gestire operazioni sulla chain-execution di un Handler:

– preHandle: richiamato prima che l’Handler corrente venga eseguito
– postHandle: richiamato dopo l’esecuzione dell’Handler corrente ma prima che la vista venga renderizzata
– afterCompletion: richiamato al completamento di tutto il flusso Request/Response

In questo articolo mostro un esempio di come effettuare un controllo sull’autenticazione dell’utente utilizzando HandlerInterceptor in un’applicazione Spring MVC. Ovviamente esistono altre soluzioni più sicure e affidabile che implementano il processo di autenticazione e access-control (vedi per esempio Spring Security). Tuttavia questo esempio può essere molto utile per capire il concetto di Interceptor e di chain-execution in Spring MVC. Per avere un’idea di quello che succede a livello temporale, ho abbozzato alcuni sequence diagram isolando i principali casi d’uso relativamente al meccanismo di autenticazione.

1 - Request for base URI

CHECK OUT THE SOURCE CODE

 

ROADMAP
STEP 1. Configurazione Spring MVC
STEP 2. Configurazione Login
STEP 3. Configurazione Interceptor

STEP 1. Configurazione Spring MVC

Creo lo skeleton dell’applicazione con Maven e aggiungo nel pom.xml le dipendenze per Spring MVC. Importo il progetto in Eclipse e imposto su di esso “Project Facets” > “Dynamic Web Module”. Questo mi permette di pubblicare l’applicazione di esempio dentro il Tomcat integrato in Eclipse e di effettuare facilmente attività di debugging. Preparo la struttura del progetto e aggiungo alcune risorse per la componente di visualizzazione delle pagine come css, immagini e librerie javascript.

 

giuseppe-urso-spring-mvc-and-interceptor-01

Definisco e configuro la Servlet Dispatcher di Spring MVC. Grazie al parametro contextConfigLocation posso definire per i file di configurazione di spring, un path personalizzato che punta alla cartella WEB-INF/spring. Ecco un’estratto del file web.xml e spring-dispatcher.xml

Creo l’instanza di Spring MVC Controller e configuro una RequestMapping che porta a una pagina di benvenuto welcome.jsp.

 

giuseppe-urso-spring-mvc-and-interceptor-03

 

STEP 2. Configurazione Login Form

Modifico il Controller per far puntare il context-root dell’applicazione a un form di login (http://localhost:8080/spring-interc/). Il Model di Spring mi servirà successivamente per avere accesso agli attributi del form di login. Creo inoltre il bean di login con gli attributi username e password e la pagina jsp per il form. Il modelAttribute del tag form:form deve avere lo stesso nome utilizzato nel Controller (“loginAttribute“).

 

STEP 3. Configurazione Interceptor

Definisco nel file spring-dispatcher.xml la mia implementazione di HandlerInterceptor che sarà in ascolto su tutte le url applicative. Per effettuare il controllo sull’autenticazione dell’utente faccio l’overriding del metodo preHandle. Utilizzo l’attributo LOGGEDIN_USER come flag per verificare se la sessione contiene o meno un utente correttamente autenticato. Inoltre faccio un controllo sull’url corrente per evitare dei redirect loop nel caso di accesso alla pagina di default oppure di submit login corretto o errato (vedi sequence diagram precedenti).

Infine aggingo tre RequestMapping nel mio Controller per mappare i casi d’uso mostrati nei sequence diagram. Il metodo di tipo POST controlla username e password inseriti nel form di login. Per motivi di praticità, non configuro un Persistence Layer basato su DB. Puttosto simulo lo strato di dati con un semplice file di testo in cui inserisco dei valori per username e password. Per accedere al file utilizzo un semplice ResourceBundle di java.util. All’avvio del Tomcat, vengono inizializzati l‘HandlerInterceptor e tutte le RequestMapping che ho definito nel mio Controller. Faccio puntare il browser al root-context applicativo http://localhost:11000/sample-interc/. La request viene intercettata da AuthenticationInterceptor che mostra la pagina di login. L’interceptor resterà sempre in ascolto su tutte le url gestite dall’Handler, per verificare la presenza o meno in Sessione di un utente correttamente autenticato.

 

giuseppe-urso-spring-mvc-and-interceptor-04

 giuseppe-urso-spring-mvc-and-interceptor-05

 

Related posts

Leave a Reply

Your email address will not be published.