Due pagine di accesso con Spring Security

1. Introduzione

In questo tutorial, vedremo come possiamo configurare Spring Security per lavorare con due diverse pagine di login utilizzando due diversi elementi http di Spring Security nella configurazione.

2. Configurazione di 2 elementi Http

Una delle situazioni in cui potremmo aver bisogno di due pagine di accesso è quando abbiamo una pagina per gli amministratori di un'applicazione e una pagina diversa per gli utenti normali.

Noi configurare due http elementi che saranno differenziati dal pattern URL associato a ciascuna:

  • / utente * per le pagine che necessitano di una normale autenticazione utente per accedere
  • / admin * per le pagine a cui accederà un amministratore

Ogni elemento http avrà una pagina di accesso diversa e un URL di elaborazione di accesso diverso.

Per configurare due diversi elementi http , creiamo due classi statiche annotate con @Configuration che estendono il WebSecurityConfigurerAdapter .

Entrambi verranno inseriti in una normale classe @Configuration :

@Configuration @EnableWebSecurity public class SecurityConfig { ... }

Definiamo il WebSecurityConfigurerAdapter per gli utenti "ADMIN" :

@Configuration @Order(1) public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { public App1ConfigurationAdapter() { super(); } @Override protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/admin*") .authorizeRequests() .anyRequest() .hasRole("ADMIN") .and() .formLogin() .loginPage("/loginAdmin") .loginProcessingUrl("/admin_login") .failureUrl("/loginAdmin?error=loginError") .defaultSuccessUrl("/adminPage") .and() .logout() .logoutUrl("/admin_logout") .logoutSuccessUrl("/protectedLinks") .deleteCookies("JSESSIONID") .and() .exceptionHandling() .accessDeniedPage("/403") .and() .csrf().disable(); } }

E ora, definiamo il WebSecurityConfigurerAdapter per gli utenti normali:

@Configuration @Order(2) public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter { public App2ConfigurationAdapter() { super(); } protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/user*") .authorizeRequests() .anyRequest() .hasRole("USER") .and() .formLogin() .loginPage("/loginUser") .loginProcessingUrl("/user_login") .failureUrl("/loginUser?error=loginError") .defaultSuccessUrl("/userPage") .and() .logout() .logoutUrl("/user_logout") .logoutSuccessUrl("/protectedLinks") .deleteCookies("JSESSIONID") .and() .exceptionHandling() .accessDeniedPage("/403") .and() .csrf().disable(); } }

Nota che inserendo l' annotazione @Order su ogni classe statica, stiamo specificando l'ordine in cui le due classi verranno considerate in base al pattern matching quando viene richiesto un URL.

Due classi di configurazione non possono avere lo stesso ordine.

3. Pagine di accesso personalizzate

Creeremo le nostre pagine di accesso personalizzate per ogni tipo di utente. Per l'utente amministratore, il modulo di accesso avrà un'azione "user_login" , come definito nella configurazione:

User login page

User:
Password:

La pagina di accesso dell'amministratore è simile, tranne per il fatto che il modulo avrà un'azione di "admin_login" secondo la configurazione java.

4. Configurazione dell'autenticazione

Ora dobbiamo configurare l'autenticazione per la nostra applicazione . Diamo un'occhiata a due modi per ottenere ciò: uno utilizzando un'origine comune per l'autenticazione dell'utente e l'altro utilizzando due origini separate.

4.1. Utilizzo di un'origine di autenticazione utente comune

Se entrambe le pagine di accesso condividono un'origine comune per l'autenticazione degli utenti, è possibile creare un singolo bean di tipo UserDetailsService che gestirà l'autenticazione.

Dimostriamo questo scenario utilizzando un InMemoryUserDetailsManager che definisce due utenti, uno con il ruolo "USER" e uno con il ruolo "ADMIN" :

@Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User .withUsername("user") .password(encoder().encode("userPass")) .roles("USER") .build()); manager.createUser(User .withUsername("admin") .password(encoder().encode("adminPass")) .roles("ADMIN") .build()); return manager; } @Bean public static PasswordEncoder encoder() { return new BCryptPasswordEncoder(); }

4.2. Utilizzo di due diverse origini di autenticazione utente

Se disponi di diverse fonti per l'autenticazione utente, una per gli amministratori e una per gli utenti normali, puoi configurare un AuthenticationManagerBuilder all'interno di ciascuna classe @Configuration statica . Diamo un'occhiata a un esempio di un gestore di autenticazione per un utente "ADMIN" :

@Configuration @Order(1) public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin") .password(encoder().encode("admin")) .roles("ADMIN"); } }

In questo caso, il bean UserDetailsService della sezione precedente non verrà più utilizzato.

6. Conclusione

In questo breve tutorial, abbiamo mostrato come implementare due diverse pagine di accesso nella stessa applicazione Spring Security.

Il codice completo per questo articolo è disponibile nel progetto GitHub.

Quando esegui l'applicazione, puoi accedere agli esempi precedenti sull'URI / protectedLinks .