All’interno di Spring Security è possibile definire il modo in cui quest’ultimo deve interagire con le informazioni utente per il loro reperimento e i successivi controlli per il login, in poche parole configurare il meccanismo di autenticazione.

La parte dedicata a ciò è l’authentication-manager che si trova dentro il file applicationContext-security.xml.

<!– Configure Authentication mechanism –>
<authentication-manager alias=”authenticationManager”>
<authentication-provider user-service-ref=”CustomUserServiceDetails”/>
</authentication-manager>
All’interno possiamo trovare il tag authentication-provider che ci permette la definizione di quale tecnologia dobbiamo utilizzare per gestire l’autenticazione, ad esempio tramite jdbc o ldap.

Nel nostro caso invece vogliamo ridefinire tutto il processo di autenticazione o meglio personalizzarlo in modo che reperisca le informazioni direttamente da Hibernate e creando nuovi ruoli legati all’utente che ci permettano di rendere la navigazione di quest’ultimo più semplice utilizzando direttamente gli strumenti nativi.

Nel tag authentication-provider è presente l’attributo user-service-ref che permette di refenziare un classe definita all’interno di spring security, nel nostro caso ad esempio:

<beans:bean id=”CustomUserServiceDetails” class=”com.gruppomcr.xxx.security.CustomUserServiceDetailsImpl” />

La classe CustomUserServiceDetailsImpl implementa l’interfaccia UserDetailsService che permette di redifinire il metodo loadUserByUsername, questo metodo ci permette di:
  • reperire le informazioni sulla username dell’utente che si stà loggando
  • personalizzare le informazioni che verranno salvate nell’oggetto UserDetails all’interno della sessione di spring security
  • utilizzare le informazioni personalizzate per meglio utilizzare gli strumenti nativi che ci offre spring

public class CustomUserServiceDetailsImpl implements UserDetailsService {

private McrUtilsGrantedAuthority mcrUtilsGrantedAuthority;

@Autowired

public void setMcrUtilsGrantedAuthorityImpl(McrUtilsGrantedAuthority mcrUtilsGrantedAuthority){

this.mcrUtilsGrantedAuthority = mcrUtilsGrantedAuthority;

}

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {

Utente utente = new Utente();

//Il set di nuove Permessi Associati che dovranno essere associati e salvati nel contesto di spring security

Collection<GrantedAuthority> gaUtente = new HashSet<GrantedAuthority>();

try {

utente = Utente.findUtenteByUsername(username);

List<String> listaFunzioniRuoli = Utente.listAuthoritiesAndRoles(utente);

if (utente == null) throw new UsernameNotFoundException(“user not found”);

gaUtente = mcrUtilsGrantedAuthority.listCustomFirGrantedAuthorities(listaFunzioniRuoli);

} catch (Exception e) {

System.out.println(“\n\n UTENTE NON TROVATO DURANTE IL LOGIN \n\n”);

utente.setPassword(“”);

}

return new CustomUserDetailsBean(username, utente.getPassword(), true, true, true, true,  gaUtente)

}

}

Analizzando meglio il metodo loadUserByUsername possiamo vedere che:

  • il parametro passato non è altro che la username inserita all’interno della form di login;
  • grazie al parametro della username, viene reperito l’utente corrispondente grazie ad Hibernate.
  • viene creata una lista di ruoli e funzioni, associati all’utente
  • viene creata una Collection<GrantedAuthorities> gaUtente, che ci consente di creare nuovi ruoli utilizzando la classe GrantedAuthoritiesImpl, molto utile nel caso in cui si voglio appiattire la relazione tra ruoli e funzionalità per generare un’unica lista di permessi/ruoli;
  • Infine viene ritornato un oggetto CustomUserDetailsBean che non è altro che un estensione/ridefinizione dell’oggetto nativo UserDetails di spring security, questo oggetto UserDetails possiede un costruttore di 7 parametri che rappresentano:
    • lo username dell’utente
    • la sua password
    • (booleano) utente abilitato
    • (booleano) account non scaduto
    • (booleano) credenziali non scadute
    • (booleano) account non bloccato
    • Lista di permessi di tipi GrantedAuthorities
  • Una volta che l’oggetto CustomUserDetailsBean è stato creato spring security si occuperà si verificare che la username e la password presenti nell’oggetto coincidano con la username e la password inseriti nel form di login:
    • se questo è vero l’oggetto verrà inserito all’interno della sessione di spring security per poter essere riutilizzato e si procederà ai successivi passi di autenticazione di spring
    • nel caso non sia vero l’autenticazione fallisce e l’utente deve riprovare di nuovo.

Il metodo listCustomFirGrantedAuthorities che è innietato si occupa di appiattire i ruoli e le funzioni dell’utente, passate come argomento e di generare la relativa lista di GrantedAuthorities che verrà salvata all’interno del CustomUserDetailsBean.

public Collection<GrantedAuthority> listCustomFirGrantedAuthorities(List<String> listaFunzioniRuoli){

Collection<GrantedAuthority> listaCustomAuthority = null;

if(listaFunzioniRuoli != null){

if(listaCustomAuthority == null){ listaCustomAuthority = new HashSet<GrantedAuthority>(); }

for (String nomeFunzionalitaRuolo : listaFunzioniRuoli) {

// Questa è la parte centrale del metodo che permette di richiamare la classe GrantedAuthorityImpl(String role) per
// creare il ruolo personalizzato ad esempio
GrantedAuthorityImpl(“mega supervisore”)
listaCustomAuthority.add(new GrantedAuthorityImpl(nomeFunzionalitaRuolo));

}

}else{

throw new IllegalArgumentException(“La listaFunzioniRuolo non può essere vuota”);

}

return listaCustomAuthority;

}

Infine l’oggetto CustomUserDetailsBean come si può vedere non è altro che una semplice estensione dell’oggetto user di spring security, ma che ci permette in un secondo momento di personalizzarlo a nostro piacimento, con le informazioni che riteniamo più utili.

public class CustomUserDetailsBean extends User implements Serializable {

public CustomUserDetailsBean(String username,

String password,

boolean enabled,

boolean accountNonExpired,

boolean credentialsNonExpired,

boolean accountNonLocked,

Collection<GrantedAuthority> authorities)

{

super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);

}

}

Tutto questa implementazione ci può essere utile immediatamente per esempio all’interno della jsp del menu principale, dove ogni gruppo di voci deve essere disponibile solo all’utente abilitato.

Utilizzando i tags che ci fornisce spring security <security:authorize>

<div xmlns:c=”http://java.sun.com/jsp/jstl/core” xmlns:jsp=”http://java.sun.com/JSP/Page” xmlns:spring=”http://www.springframework.org/tags&#8221;

xmlns:security=”http://www.springframework.org/security/tags&#8221; version=”2.0″>

<security:authorize access=”hasRole(‘mega supervisore‘)”>

<div id=”admin_Id”>
<!– codice della jsp –>
</div>

</security:authorize>

In questo modo soltanto  gli utenti loggati che possiedono il ruolo personalizzato “mega supervisore” potranno vedere la parte di codice della jsp che si trova all’interno dei tag security

Qui trovate alcuni link che vi possono spiegare come funziona questa parte del management dell’autorizzazione in spring sec.

http://docs.huihoo.com/spring/spring-security/3.0.x/core-services.html

http://loianegroner.com/2010/01/tutorial-getting-started-with-spring-security/

http://java.dzone.com/tips/pathway-acegi-spring-security-

Annunci