Autorità concessa rispetto al ruolo in Spring Security

1. Panoramica

In questo rapido articolo, spiegheremo la sottile ma significativa differenza tra un ruolo e un'autorità concessa in Spring Security . Per informazioni più dettagliate su ruoli e autorità, vedere l'articolo qui.

2. GrantedAuthority

In Spring Security, possiamo pensare a ogni GrantedAuthority come a un privilegio individuale . Gli esempi potrebbero includere READ_AUTHORITY , WRITE_PRIVILEGE o anche CAN_EXECUTE_AS_ROOT . La cosa importante da capire è che il nome è arbitrario .

Quando si utilizza direttamente un GrantedAuthority , ad esempio tramite un'espressione come hasAuthority ("READ_AUTHORITY"), limitiamo l'accesso in modo dettagliato .

Come probabilmente puoi intuire, possiamo fare riferimento al concetto di autorità usando anche i privilegi .

3. Ruolo come autorità

Allo stesso modo, in Spring Security, possiamo pensare a ciascun ruolo come a GrantedAuthority a grana grossa rappresentata come una stringa e preceduta da " ROLE " . Quando si utilizza un ruolo direttamente, ad esempio tramite un'espressione come hasRole ("ADMIN") , si limita l'accesso in modo grossolano.

Vale la pena notare che il prefisso " ROLE" predefinito è configurabile, ma spiegare come farlo va oltre lo scopo di questo articolo.

La differenza fondamentale tra questi due è la semantica che attribuiamo al modo in cui utilizziamo la funzionalità. Per il framework, la differenza è minima e fondamentalmente si occupa di questi esattamente nello stesso modo.

4. Ruolo come contenitore

Ora che abbiamo visto come il framework utilizza il concetto di ruolo , discutiamo rapidamente anche di un'alternativa, ovvero l' utilizzo dei ruoli come contenitori di autorità / privilegi .

Questo è un approccio di livello superiore ai ruoli, rendendoli un concetto più orientato al business piuttosto che incentrato sull'implementazione.

Il framework Spring Security non fornisce alcuna guida in termini di come dovremmo utilizzare il concetto, quindi la scelta è interamente specifica dell'implementazione.

5. Configurazione Spring Security

Possiamo dimostrare un requisito di autorizzazione granulare limitando l'accesso a / protectedbyauthority agli utenti con READ_AUTHORITY .

Possiamo dimostrare un requisito di autorizzazione a grana grossa limitando l'accesso a / protectedbyrole agli utenti con ROLE_USER .

Configuriamo un tale scenario nella nostra configurazione di sicurezza:

@Override protected void configure(HttpSecurity http) throws Exception { // ... .antMatchers("/protectedbyrole").hasRole("USER") .antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE") // ... }

6. Simple Data Init

Ora che comprendiamo meglio i concetti di base, parliamo della creazione di alcuni dati di configurazione all'avvio dell'applicazione.

Questo è, ovviamente, un modo molto semplice per farlo, per iniziare con alcuni utenti di test preliminari durante lo sviluppo, non il modo in cui dovresti gestire i dati in produzione.

Ascolteremo l'evento di aggiornamento del contesto:

@Override @Transactional public void onApplicationEvent(ContextRefreshedEvent event) { MyPrivilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE"); MyPrivilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE"); }

L'implementazione effettiva qui non ha molta importanza e, in generale, dipende dalla soluzione di persistenza che stai utilizzando. Il punto principale è che stiamo insistendo sulle autorità che stiamo usando nel codice.

7. UserDetailsService

La nostra implementazione di UserDetailsService è dove avviene la mappatura delle autorità . Una volta che l'utente si è autenticato, il nostro metodo getAuthorities () popola e restituisce un oggetto UserDetails :

private Collection getAuthorities( Collection roles) { List authorities = new ArrayList(); for (Role role: roles) { authorities.add(new SimpleGrantedAuthority(role.getName())); role.getPrivileges().stream() .map(p -> new SimpleGrantedAuthority(p.getName())) .forEach(authorities::add); } return authorities; }

8. Esecuzione e verifica dell'esempio

Possiamo eseguire l' applicazione Java di esempio RolesAuthoritiesApplication , che si trova nel progetto GitHub.

Per vedere l'autorizzazione basata sui ruoli in azione, dobbiamo:

  • Accesso // localhost: 8082 / protectedbyrole
  • Autentica come [protetto da email] (la password è "utente" )
  • Annotare l'autorizzazione riuscita
  • Accesso // localhost: 8082 / protectedbyauthority
  • Nota autorizzazione non riuscita

Per vedere l'autorizzazione basata sull'autorità in azione, è necessario disconnettersi dall'applicazione e quindi:

  • Accesso // localhost: 8082 / protectedbyauthority
  • Autentica come [protetto da email] / admin
  • Annotare l'autorizzazione riuscita
  • Accesso // localhsot: 8082 / protectedbyrole
  • Nota autorizzazione non riuscita

9. Conclusione

In questo breve tutorial, abbiamo esaminato la sottile ma significativa differenza tra un ruolo e un'autorità concessa in Spring Security.