Configuration automatique de la sécurité Spring Boot

1. Introduction

Dans cet article, nous allons jeter un œil à l'approche avisée de Spring Boot en matière de sécurité.

En termes simples, nous allons nous concentrer sur la configuration de sécurité par défaut et sur la façon dont nous pouvons la désactiver ou la personnaliser si nécessaire.

2. Configuration de la sécurité par défaut

Afin d'ajouter la sécurité à notre application Spring Boot, nous devons ajouter la dépendance de démarrage de sécurité :

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

Cela inclura la classe SecurityAutoConfiguration - contenant la configuration de sécurité initiale / par défaut.

Remarquez que nous n'avons pas spécifié la version ici, en supposant que le projet utilise déjà Boot comme parent.

En termes simples, par défaut, l'authentification est activée pour l'application. En outre, la négociation de contenu est utilisée pour déterminer si basic ou formLogin doit être utilisé.

Il existe des propriétés prédéfinies, telles que:

spring.security.user.name spring.security.user.password

Si nous ne configurons pas le mot de passe à l'aide de la propriété prédéfinie spring.security.user.password et que nous démarrons l'application, nous remarquerons qu'un mot de passe par défaut est généré de manière aléatoire et imprimé dans le journal de la console:

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

Pour plus de valeurs par défaut, consultez la section des propriétés de sécurité de la page de référence des propriétés communes de l'application Spring Boot.

3. Désactivation de la configuration automatique

Pour annuler la configuration automatique de la sécurité et ajouter notre propre configuration, nous devons exclure la classe SecurityAutoConfiguration .

Cela peut être fait via une simple exclusion:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) public class SpringBootSecurityApplication { public static void main(String[] args) { SpringApplication.run(SpringBootSecurityApplication.class, args); } } 

Ou en ajoutant une configuration dans le fichier application.properties :

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

Il existe également des cas particuliers dans lesquels cette configuration ne suffit pas.

Par exemple, presque chaque application Spring Boot est démarrée avec Actuator dans le chemin de classe. Cela pose des problèmes car une autre classe de configuration automatique a besoin de celle que nous venons d'exclure , de sorte que l'application ne démarrera pas.

Afin de résoudre ce problème, nous devons exclure cette classe; et, spécifique à la situation de l'actionneur, nous devons exclure ManagementWebSecurityAutoConfiguration .

3.1. Désactivation ou dépassement de la configuration automatique de la sécurité

Il y a une différence significative entre la désactivation de la configuration automatique et sa dépassement.

En le désactivant, c'est comme ajouter la dépendance Spring Security et toute la configuration à partir de zéro. Cela peut être utile dans plusieurs cas:

  1. Intégration de la sécurité des applications avec un fournisseur de sécurité personnalisé
  2. Migration d'une application Spring héritée avec une configuration de sécurité déjà existante - vers Spring Boot

Mais, la plupart du temps, nous n'aurons pas besoin de désactiver complètement la configuration automatique de la sécurité.

La façon dont Spring Boot est configuré permet de surpasser la sécurité autoconfigurée en ajoutant nos nouvelles classes de configuration personnalisées. C'est généralement plus facile, car nous personnalisons simplement une configuration de sécurité existante pour répondre à nos besoins.

4. Configuration de la sécurité Spring Boot

Si nous avons choisi la voie de la désactivation de la configuration automatique de la sécurité, nous devons naturellement fournir notre propre configuration.

Comme nous l'avons vu précédemment, il s'agit de la configuration de sécurité par défaut; nous pouvons le personnaliser en modifiant le fichier de propriétés.

Nous pouvons, par exemple, remplacer le mot de passe par défaut en ajoutant le nôtre:

spring.security.user.password=password

Si nous voulons une configuration plus flexible, avec plusieurs utilisateurs et rôles par exemple, nous devons utiliser une classe @Configuration complète :

@Configuration @EnableWebSecurity public class BasicConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth .inMemoryAuthentication() .withUser("user") .password(encoder.encode("password")) .roles("USER") .and() .withUser("admin") .password(encoder.encode("admin")) .roles("USER", "ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic(); } }

L' annotation @EnableWebSecurity est cruciale si nous désactivons la configuration de sécurité par défaut.

S'il manque, l'application ne démarrera pas. L'annotation n'est facultative que si nous remplaçons simplement le comportement par défaut à l'aide d'un WebSecurityConfigurerAdapter .

Also, notice that we need to use the PasswordEncoder to set the passwords when using Spring Boot 2. For more details, see our guide on the Default Password Encoder in Spring Security 5.

Now, we should verify that our security configuration applies correctly by with a couple of quick live tests:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) public class BasicConfigurationIntegrationTest { TestRestTemplate restTemplate; URL base; @LocalServerPort int port; @Before public void setUp() throws MalformedURLException { restTemplate = new TestRestTemplate("user", "password"); base = new URL("//localhost:" + port); } @Test public void whenLoggedUserRequestsHomePage_ThenSuccess() throws IllegalStateException, IOException { ResponseEntity response = restTemplate.getForEntity(base.toString(), String.class); assertEquals(HttpStatus.OK, response.getStatusCode()); assertTrue(response.getBody().contains("Baeldung")); } @Test public void whenUserWithWrongCredentials_thenUnauthorizedPage() throws Exception { restTemplate = new TestRestTemplate("user", "wrongpassword"); ResponseEntity response = restTemplate.getForEntity(base.toString(), String.class); assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); assertTrue(response.getBody().contains("Unauthorized")); } }

The idea is that behind Spring Boot Security is, in fact, Spring Security, so any security configuration that can be done with this one, or any integration this one supports can be also implemented into Spring Boot.

5. Spring Boot OAuth2 Auto-Configuration (using legacy stack)

Spring Boot has a dedicated auto-configuration support for OAuth2.

Spring Security OAuth support that came with Spring Boot 1.x was removed in later boot versions in lieu of first class OAuth support that comes bundled with Spring Security 5. We'll see how to use that in the next section.

For the legacy stack (using Spring Security OAuth), first we'll need to add a Maven dependency to start setting up our application:

 org.springframework.security.oauth spring-security-oauth2 

This dependency includes a set of classes that are capable of triggering the auto-configuration mechanism defined in OAuth2AutoConfiguration class.

Now, we have multiple choices to continue, depending on the scope of our application.

5.1. OAuth2 Authorization Server Auto-Configuration

If we want our application to be an OAuth2 provider, we can use @EnableAuthorizationServer.

On startup, we'll notice in the logs that the auto-configuration classes will generate a client id and a client-secret for our authorization server and of course a random password for basic authentication.

Using default security password: a81cb256-f243-40c0-a585-81ce1b952a98 security.oauth2.client.client-id = 39d2835b-1f87-4a77-9798-e2975f36972e security.oauth2.client.client-secret = f1463f8b-0791-46fe-9269-521b86c55b71

These credentials can be used to obtain an access token:

curl -X POST -u 39d2835b-1f87-4a77-9798-e2975f36972e:f1463f8b-0791-46fe-9269-521b86c55b71 \ -d grant_type=client_credentials -d username=user -d password=a81cb256-f243-40c0-a585-81ce1b952a98 \ -d scope=write //localhost:8080/oauth/token

Our another article provides further details on the subject.

5.2. Other Spring Boot OAuth2 Auto-Configuration Settings

There are some other use cases covered by Spring Boot OAuth2 like:

  1. Resource Server – @EnableResourceServer
  2. Client Application – @EnableOAuth2Sso or @EnableOAuth2Client

If we need our application to be one of the types above we just have to add some configuration to application properties, as detailed by the links referenced above.

All OAuth2 specific properties can be found at Spring Boot Common Application Properties.

6. Spring Boot OAuth2 Auto-Configuration (using new stack)

To use the new stack, we need to add dependencies based on what we want to configure – an authorization server, a resource server or a client application.

Let's look at them one by one.

6.1. OAuth2 Authorization Server Support

As we saw in the previous section, the Spring Security OAuth stack offered the possibility of setting up an Authorization Server as a Spring Application. But the project has been deprecated and Spring does not support its own authorization server as of now. Instead, it's recommended to use existing well-established providers such as Okta, Keycloak, and Forgerock.

However, Spring Boot does make it easy for us to configure such providers. For an example Keycloak configuration, we can refer to either A Quick Guide to Using Keycloak with Spring Boot or Keycloak Embedded in a Spring Boot Application.

6.2. OAuth2 Resource Server Support

To include support for a resource server, we need to add this dependency:

 org.springframework.boot spring-boot-starter-oauth2-resource-server 

For the latest version information, head over to Maven Central.

Additionally, in our security configuration, we need to include the oauth2ResourceServer() DSL:

@Configuration public class JWTSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http ... .oauth2ResourceServer(oauth2 -> oauth2.jwt()); ... } }

Our OAuth 2.0 Resource Server With Spring Security 5 gives an in-depth view of this topic.

6.3. OAuth2 Client Support

Similar to how we configured a resource server, a client application also needs its own dependencies and DSLs.

Here's the specific dependency for OAuth2 client support:

 org.springframework.boot spring-boot-starter-oauth2-client  

The latest version can be found at Maven Central.

Spring Security 5 also provides first-class login support via its oath2Login() DSL.

For details on SSO support in the new stack, please refer to our Simple Single Sign-On with Spring Security OAuth2.

7. Spring Boot 2 Security vs Spring Boot 1 Security

Compared to Spring Boot 1, Spring Boot 2 has greatly simplified the auto-configuration.

In Spring Boot 2, if we want our own security configuration, we can simply add a custom WebSecurityConfigurerAdapter. This will disable the default auto-configuration and enable our custom security configuration.

Spring Boot 2 uses most of Spring Security’s defaults. Because of this, some of the endpoints that were unsecured by default in Spring Boot 1 are now secured by default.

These endpoints include static resources such as /css/**, /js/**, /images/**, /webjars/**, /**/favicon.ico, and the error endpoint. If we need to allow unauthenticated access to these endpoints, we can explicitly configure that.

To simplify the security-related configuration, Spring Boot 2 has removed the following Spring Boot 1 properties:

security.basic.authorize-mode security.basic.enabled security.basic.path security.basic.realm security.enable-csrf security.headers.cache security.headers.content-security-policy security.headers.content-security-policy-mode security.headers.content-type security.headers.frame security.headers.hsts security.headers.xss security.ignored security.require-ssl security.sessions

8. Conclusion

In this article, we focused on the default security configuration provided by Spring Boot. We saw how the security auto-configuration mechanism can be disabled or overridden and how a new security configuration can be applied.

Le code source pour OAuth2 se trouve sur notre référentiel OAuth2 GitHub, pour l'ancienne et la nouvelle pile. Le reste du code peut être trouvé sur les tutoriels GitHub.