Deux pages de connexion avec Spring Security

1. Introduction

Dans ce didacticiel, nous verrons comment nous pouvons configurer Spring Security pour qu'il fonctionne avec deux pages de connexion différentes en utilisant deux éléments http Spring Security différents dans la configuration.

2. Configuration de 2 éléments Http

L'une des situations dans lesquelles nous pouvons avoir besoin de deux pages de connexion est lorsque nous avons une page pour les administrateurs d'une application et une page différente pour les utilisateurs normaux.

Nous allons configurer deux éléments http qui seront différenciés par le modèle d'URL associé à chacun:

  • / user * pour les pages qui auront besoin d'une authentification utilisateur normale pour être accédées
  • / admin * pour les pages auxquelles un administrateur accédera

Chaque élément http aura une page de connexion différente et une URL de traitement de connexion différente.

Afin de configurer deux éléments http différents , créons deux classes statiques annotées avec @Configuration qui étendent WebSecurityConfigurerAdapter .

Les deux seront placés dans une classe @Configuration standard :

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

Définissons le WebSecurityConfigurerAdapter pour les utilisateurs «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(); } }

Et maintenant, définissons le WebSecurityConfigurerAdapter pour les utilisateurs normaux:

@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(); } }

Notez qu'en plaçant l' annotation @Order sur chaque classe statique, nous spécifions l'ordre dans lequel les deux classes seront considérées en fonction du motif correspondant lorsqu'une URL est demandée.

Deux classes de configuration ne peuvent pas avoir le même ordre.

3. Pages de connexion personnalisées

Nous créerons nos propres pages de connexion personnalisées pour chaque type d'utilisateur. Pour l'utilisateur administrateur, le formulaire de connexion aura une action «user_login» , comme défini dans la configuration:

User login page

User:
Password:

La page de connexion de l'administrateur est similaire, sauf que le formulaire aura une action «admin_login» selon la configuration java.

4. Configuration de l'authentification

Nous devons maintenant configurer l'authentification pour notre application . Examinons deux façons d'accomplir cela: l'une en utilisant une source commune pour l'authentification des utilisateurs et l'autre en utilisant deux sources distinctes.

4.1. Utilisation d'une source d'authentification utilisateur commune

Si les deux pages de connexion partagent une source commune d'authentification des utilisateurs, vous pouvez créer un seul bean de type UserDetailsService qui gérera l'authentification.

Démontrons ce scénario à l'aide d'un InMemoryUserDetailsManager qui définit deux utilisateurs - un avec le rôle «USER» et l'autre avec un rôle «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. Utilisation de deux sources d'authentification utilisateur différentes

Si vous disposez de différentes sources pour l'authentification des utilisateurs - une pour les administrateurs et une pour les utilisateurs normaux - vous pouvez configurer un AuthenticationManagerBuilder dans chaque classe @Configuration statique . Regardons un exemple de gestionnaire d'authentification pour un utilisateur «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"); } }

Dans ce cas, le bean UserDetailsService de la section précédente ne sera plus utilisé.

6. Conclusion

Dans ce tutoriel rapide, nous avons montré comment implémenter deux pages de connexion différentes dans la même application Spring Security.

Le code complet de cet article se trouve dans le projet GitHub.

Lorsque vous exécutez l'application, vous pouvez accéder aux exemples ci-dessus sur l' URI / protectedLinks .