Primi Passi con Spring Security (parte 3)

Introduzione

Negli articoli precedenti della serie abbiamo parlato prevalentemente di autenticazione degli utenti, fornendo solamente un rapido accenno alla questione delle autorizzazioni. L’estrema potenza e semplicità del framework Spring Security è particolarmente evidente nella gestione delle ACL (Accesso Control List) che possono essere espresse semplicemente mediante Spring Expression Language (SpEL). Ma iniziamo per gradi parlando innanzitutto del concetto di ruolo e privilegio.

Ruoli e Privilegi

Da un punto di vista teorico in un sistema Rule Based ACL il concetto di ruolo è utilizzato per indicare una funzioni che un utente può assumere sul sistema (es. admin, editor, etc.) mentre i privilegi sono specifiche autorizzazioni associate ad un ruolo (es. lettura o scrittura di un campo).

In Spring Security questa distinzione non è molto netta e spesso ruoli (o Rule) e privilegi (o Authority) sono intercambiabili al punto che l’interfaccia UserDetails, introdotta nell’articolo Primi Passi con Spring Security (parte 2), presenta un solo metodo getAuthorities() che restituisce sia i ruoli che i privilegi come stringhe.

La distinzione tra ruoli e privilegi avviene semplicemente utilizzando il prefisso ROLE. Ad esempio il seguente XML definisce tre utenti: il primo user ha il ruolo USER, il secondo reader ha il permesso CAN_READ, mentre il terzo admin ha sia il ruolo USER che i permesso CAN_READ.

Privilegi e ruoli possono essere utilizzati per sia per controllare l’accesso ad una intera pagina web (full page authorization), che per visualizzare o meno porzioni di pagina (in page authorization).

Full Page Authorization

L’accesso ad una specifica pagina è controllabile filtrandone opportunamente l’URL attraverso il tag <intercept-url> all’interno del tag <html> dove abbiamo abilitato l’uso delle espressioni. Fondamentalmente il tag prevede due attributi:

  • pattern: definisce l’URL filtrato anche utilizzando espressioni con *;
  • access: definisce ruoli o privilegi che possono accedere utilizzando opportune espressioni.

La seguente porzione di codice XML definisce alcuni semplici interceptor. Le espressioni utilizzate per il controllo degli accessi sono sufficientemente intuitive ma vengono comunque descritte nel seguito dell’articolo.

Si noti che Spring valuta i filtri nell’ordine in cui compaiono, caratteristica che può essere utilizzata per definire accessi ad aree dell’applicazione in modo puntuale. Nell’esempio, infatti, tutte le pagine della cartella views sono accessibili agli utenti autenticati (ultima regola nell’elenco), ad eccezione delle pagine user.jsp, canRead.jsp e denyAll.jsp che hanno filtri specifici. Se l’ordine delle regole fosse stato invertito, tutte le pagine sotto views sarebbero state visibili a tutti gli utenti indipendentemente da ruoli e privilegi, perchè la prima regola sarebbe stata applicata senza valutare le successive.

In Page Authorization

In questo caso è possibile “profilare” il contenuto di una pagina autorizzando solamente utenti con determinati ruoli o privilegi alla visualizzazione delle informazioni associate. Per farlo è innanzitutto necessario introdurre la dipendenza alla tag library di Spring Security:

Successivamente dobbiamo abilitare il security namespace sulla pagina ed utilizzarlo per profilare le porzioni di codice di interesse:

Espressioni Comuni

Le espressioni utilizzate per il controllo degli accessi sono valutate su un root object che è parte del contesto di Spring. L’oggetto root di base è SecurityExpressionRoot e definisce termini e predicati di sicurezza comuni, disponibili sia in un contesto web che per la sicurezza dei metodi (non analizzati in questo articolo). La seguente tabella elenca le espressioni più comuni.

hasRole([role])
hasAnyRole([role1,role2])
Restituisce TRUE se l’utente corrente ha il ruolo o uno dei ruoli elencati.
hasAuthority([authority])
hasAnyAuthority([authority1,authority2])
Restituisce TRUE se l’utente corrente ha il profilo o uno dei profili elencati.
permitAll Restituisce sempre TRUE.
 denyAll Restituisce sempre FALSE.
 isAnonymous() Restituisce TRUE se l’utente corrente è anonimo.
isRememberMe() Restituisce TRUE se l’utente corrente è stato riconosciuto in quanto aveva una sessione già aperta.
isAuthenticated() Restituisce TRUE se l’utente non è anonimo.
isFullyAuthenticated() restituisce TRUE se l’utente non è anonimo e non proviene da una sessione precedente (remember me). Utilizzato per forzare nuovamente l’accesso.
principal
authentication
Termini che consentono l’accesso alle informazioni associate all’utente corrente ad esempio per essere visualizzate su una pagina jsp:
hasIpAddress(ipAddr) In ambito web limita l’accesso ai soli client con l’ip specificato.

Personalizzazione

Se si desidera è possibile personalizzare o estendere le espressioni utilizzate per il controllo degli accessi semplicemente definendo un bean (gestito da Spring) ed utilizzandolo come una normale espressione. Ad esempio il seguente metodo check del bean WebSecurity:

Può essere utilizzato nel tag <intercept-url> nel seguente modo:

E’ possibile anche utilizzare metodi che referenziano path variable definiti nell’URL dell’attributo pattern, ad esempio:

Codice Sorgente

Il codice sorgente completo degli esempi presentati è scaricabile qui spring-security.

How useful was this post?

Click on a star to rate it!

Average rating 3 / 5. Vote count: 2

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!