domenica 27 dicembre 2009

Spring Security: personalizzare l'authentication provider

Abbiamo già visto come gestire la sicurezza con Spring Security.
Come avevamo visto il framework si basa su una logica di authentication-manager, authentication-provider. Ci sono già alcune implementazioni pronte: molto comoda è quella in memoria, specialmente per il testing.
Altra implementazione "comoda" è quella JdbcDao. Il limite di questa implementazione è che il db da cui pescare i dati deve per forza essere fatto in un certo modo, anche se si possono specificare le query da eseguire, ma la flessibilità non è al 100%.
Mi sono quindi detto: proviamo ad implementare il mio provider.
Devo implementare l'interfaccia AuthenticationProvider che ha un unico metodo authenticate
Il metodo deve verificare che l'utente si possa autenticare e restituisce un oggetto Authentication, che porta con se lo username e le GrantedAuthority a cui appartiene, praticamente i ruoli dell'utente.

Vediamo un po' di codice...

public Authentication authenticate(Authentication auth) throws AuthenticationException {
        String username = auth.getPrincipal().toString();
        String password = auth.getCredentials().toString();
        if (!"Andrea".equals(username))
            throw new BadCredentialsException("Nome Utente non valido!");
        if (!"Andrea".equals(password))
            throw new BadCredentialsException("Password Errata!");
        Collection gas = new ArrayList();
        GrantedAuthority ga = new AndreaGrantedAuthority("G1");
        gas.add(ga);
        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(username, password, gas);       
        return result;
    }


La cosa veramente da notare e che, lo confesso, mi ha un po' spiazzato, sono le prime 2 righe, cioè il reperimento di username e password.
Soprattutto la password non era lampante. Poi, studiando un po' di teoria, ho visto che siamo nello standard. L'oggetto Authentication viene passato in ingresso e, se tutto va a buon fine, ne viene rilasciato un'altro in uscita. Nel mio caso ho usato un UsernamePasswordAuthenticationToken, che è già a corredo del framework.
Per dare i ruoli all'utente ho usato una classe AndreaGrantedAuthority che implementa l'interfaccia GrantedAuthority.
Questa classe deve essere poi dichiarata come
security:authentication-provider ref="myAuthenticationProvider"
il tag ref indica che ci dovrà essere un bean spring fatto + o meno così

bean id="myAuthenticationProvider" class="it.andrea.AndreaAuthenticationProvider"

E' ovvio quindi che questo bean è perfettamente integrato in Spring: é quindi possibile iniettare SessionFactory e quant'altro ci possa servire per il reperimento dei dati dell'utente: io per brevità non lo ho fatto ma posso assicurare che funziona.

Da dire che così il gioco non può funzionare, perchè il nostro provider vuole anche uno UserDetailService al quale chiedere com'è fatto l'utente. Infatti il provider si è solo chiesto se l'utente era abilitato o no, non quale fosse in dettaglio il suo profilo.

Per lo UserDetailService mi riprometto di scrivere un nuovo articolo.

Nessun commento:

Posta un commento