Connexion au formulaire de sécurité Spring

1. Introduction

Cet article va se concentrer sur la connexion avec Spring Security . Nous allons nous appuyer sur le simple exemple précédent de Spring MVC, car c'est une partie nécessaire de la configuration de l'application Web avec le mécanisme de connexion.

2. Les dépendances de Maven

Lorsque vous travaillez avec Spring Boot, le démarreur spring-boot-starter-security inclura automatiquement toutes les dépendances telles que spring-security-core , spring-security-web et spring-security-config, entre autres:

 org.springframework.boot spring-boot-starter-security 2.3.3.RELEASE 

Si nous n'utilisons pas Spring Boot, veuillez consulter l'article Spring Security with Maven, qui décrit comment ajouter toutes les dépendances requises. Les deux standards spring-security-web et spring-security-config seront requis.

3. Configuration Java de Spring Security

Commençons par créer une classe de configuration Spring Security qui étend WebSecurityConfigurerAdapter.

En ajoutant @EnableWebSecurity , nous obtenons la prise en charge de l'intégration Spring Security et MVC:

@Configuration @EnableWebSecurity public class SecSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // authentication manager (see below) } @Override protected void configure(final HttpSecurity http) throws Exception { // http builder configurations for authorize requests and form login (see below) } }

Dans cet exemple, nous avons utilisé l'authentification en mémoire et défini 3 utilisateurs.

Ensuite, nous passons en revue les éléments que nous avons utilisés pour créer la configuration de connexion du formulaire.

Créons d'abord notre gestionnaire d'authentification.

3.1. Gestionnaire d'authentification

Le fournisseur d'authentification est soutenu par une implémentation simple en mémoire - InMemoryUserDetailsManager en particulier. Ceci est utile pour le prototypage rapide lorsqu'un mécanisme de persistance complet n'est pas encore nécessaire:

protected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER") .and() .withUser("user2").password(passwordEncoder().encode("user2Pass")).roles("USER") .and() .withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN"); }

Ici, nous configurons trois utilisateurs avec le nom d'utilisateur, le mot de passe et le rôle codés en dur.

À partir de Spring 5, nous devons également définir un encodeur de mot de passe . Dans notre exemple, nous avons utilisé le BCryptPasswordEncoder:

@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

Ensuite, configurons HttpSecurity.

3.2. Configuration pour autoriser les demandes

Nous commençons par faire les configurations nécessaires pour autoriser les demandes.

Ici, nous autorisons l'accès anonyme sur / login afin que les utilisateurs puissent s'authentifier. Restreindre / admin aux rôles ADMIN et sécuriser tout le reste:

@Override protected void configure(final HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() .antMatchers("/login*").permitAll() .anyRequest().authenticated() .and() // ... }

Notez que l'ordre des éléments antMatchers () est significatif - les règles les plus spécifiques doivent venir en premier, suivies des règles plus générales .

3.3. Configuration pour la connexion par formulaire

Ensuite, nous étendons la configuration ci-dessus pour la connexion et la déconnexion par formulaire:

@Override protected void configure(final HttpSecurity http) throws Exception { http // ... .and() .formLogin() .loginPage("/login.html") .loginProcessingUrl("/perform_login") .defaultSuccessUrl("/homepage.html", true) .failureUrl("/login.html?error=true") .failureHandler(authenticationFailureHandler()) .and() .logout() .logoutUrl("/perform_logout") .deleteCookies("JSESSIONID") .logoutSuccessHandler(logoutSuccessHandler()); }
  • loginPage () - la page de connexion personnalisée
  • loginProcessingUrl () - l'URL à laquelle soumettre le nom d'utilisateur et le mot de passe
  • defaultSuccessUrl () - la page de destination après une connexion réussie
  • failureUrl () - la page de destination après une connexion infructueuse
  • logoutUrl () - la déconnexion personnalisée

4. Ajoutez Spring Security à l'application Web

Pour utiliser la configuration Spring Security définie ci-dessus, nous devons la joindre à l'application Web.

Nous utiliserons WebApplicationInitializer , nous n'avons donc pas besoin de fournir de web.xml:

public class AppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext sc) { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(SecSecurityConfig.class); sc.addListener(new ContextLoaderListener(root)); sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain")) .addMappingForUrlPatterns(null, false, "/*"); } }

Notez que cet initialiseur n'est pas nécessaire si nous utilisons une application Spring Boot. Consultez notre article sur la configuration automatique de la sécurité Spring Boot pour plus de détails sur la façon dont la configuration de sécurité est chargée dans Spring Boot.

5. La configuration XML de Spring Security

Jetons également un œil à la configuration XML correspondante.

Le projet global utilise la configuration Java, nous devons donc importer le fichier de configuration XML via une classe Java @Configuration :

@Configuration @ImportResource({ "classpath:webSecurityConfig.xml" }) public class SecSecurityConfig { public SecSecurityConfig() { super(); } }

Et la configuration XML de Spring Security - webSecurityConfig.xml :

6. Le web.xml

Avant l'introduction de Spring 4 , nous avions l'habitude de configurer la configuration de Spring Security dans le fichier web.xml - seul un filtre supplémentaire ajouté au standard Spring MVC web.xml :

Spring Secured Application     springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy   springSecurityFilterChain /* 

Le filtre - DelegatingFilterProxy - délègue simplement à un bean géré par Spring - le FilterChainProxy - qui lui-même est en mesure de bénéficier d'une gestion complète du cycle de vie du bean Spring, etc.

7. Le formulaire de connexion

La page du formulaire de connexion va être enregistrée avec Spring MVC en utilisant le mécanisme simple pour mapper les noms de vues à des URL sans avoir besoin d'un contrôleur explicite entre les deux:

registry.addViewController("/login.html");

This, of course, corresponds to the login.jsp:


    
User:
Password:

The Spring Login form has the following relevant artifacts:

  • login – the URL where the form is POSTed to trigger the authentication process
  • username – the username
  • password – the password

8. Further Configuring Spring Login

We briefly discussed a few configurations of the login mechanism when we introduced the Spring Security Configuration above – let's go into some detail now.

One reason to override most of the defaults in Spring Security is to hide the fact that the application is secured with Spring Security and minimize the information a potential attacker knows about the application.

Fully configured, the login element looks like this:

@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/login.html") .loginProcessingUrl("/perform_login") .defaultSuccessUrl("/homepage.html",true) .failureUrl("/login.html?error=true") }

Or the corresponding XML configuration:

8.1. The Login Page

Next, let's see how we can configure a custom login page using the loginPage() method:

http.formLogin() .loginPage("/login.html")

Or, via XML configuration:

login-page='/login.html'

If we don't specify this, Spring Security will generate a very basic Login Form at the /login URL.

8.2. The POST URL for Login

The default URL where the Spring Login will POST to trigger the authentication process is /login which used to be /j_spring_security_check before Spring Security 4.

We can use the loginProcessingUrl method to override this URL:

http.formLogin() .loginProcessingUrl("/perform_login")

Or, via XML configuration:

login-processing-url="/perform_login"

A good reason to override this default URL is to hide the fact that the application is actually secured with Spring Security – that information should not be available externally.

8.3. The Landing Page on Success

After a successful login process, the user is redirected to a page – which by default is the root of the web application.

We can override this via the defaultSuccessUrl() method:

http.formLogin() .defaultSuccessUrl("/homepage.html")

Or with XML configuration:

default-target-url="/homepage.html"

In case the always-use-default-target is set to true, then the user is always redirected to this page. If that attribute is set to false, then the user will be redirected to the previous page they wanted to visit before being prompted to authenticate.

8.4. The Landing Page on Failure

Same as with the Login Page, the Login Failure Page is autogenerated by Spring Security at /login?error by default.

To override this, we can use the failureUrl() method:

http.formLogin() .failureUrl("/login.html?error=true")

Or with XML:

authentication-failure-url="/login.html?error=true"

9. Conclusion

Dans cet exemple de connexion Spring , nous avons configuré un processus d'authentification simple - nous avons discuté du formulaire de connexion Spring Security, de la configuration de la sécurité et de certaines des personnalisations les plus avancées disponibles.

L'implémentation de ce tutoriel Spring Login peut être trouvée dans le projet GitHub - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.

Lorsque le projet s'exécute localement, l'exemple HTML est accessible à l'adresse:

//localhost:8080/spring-security-mvc-login/login.html