Aller au contenu

Spring Boot Security

Quelques concepts

A quoi sert le remember-me dans Spring ?

Le paramètre remember-me dans Spring est utilisé pour activer ou désactiver la fonctionnalité de mémorisation des informations d’authentification de l’utilisateur sur un site web.

Lorsqu’il est activé, il permet à l’utilisateur de rester connecté sur le site même après avoir fermé le navigateur ou redémarré l’ordinateur (en conservant sa session d’authentification active pendant une période prédéfinie).

Pourquoi utiliser cette fonctionnalité ?

Pour offrir une meilleure expérience utilisateur en évitant à ce dernier de devoir se reconnecter en permanence (pratique pour les sites web qui requièrent une authentification régulière, tels que les sites de e-commerce, applications bancaires et réseaux sociaux).

Comme nous l’avons déjà vu dans d’autres parties du cours et des exemples sur Spring Security (module de sécurité de Spring), ce dernier offre une prise en charge intégrée du remember-me avec des fonctionnalités de configuration et de personnalisation.

Que fait Spring si remember-me est activé ?

Il y a génération d’un cookie côté serveur ou un autre mécanisme de stockage sécurisé pour mémoriser les informations d’authentification de l’utilisateur (telles que son nom d’utilisateur ou son identifiant. Lorsque l’utilisateur revient sur le site, Spring Security utilise ces informations pour restaurer la session d’authentification de l’utilisateur et lui permettre ainsi d’accéder aux ressources protégées sans avoir à se reconnecter !)

Remarque : L’utilisation du remember-me peut présenter des considérations en matière de sécurité, notamment en ce qui concerne la durée de validité du cookie ou des informations d’authentification stockées, ainsi que la manière dont les informations sont cryptées et protégées. Il est donc essentiel de configurer et d’utiliser cette fonctionnalité de manière appropriée, en tenant compte des meilleures pratiques de sécurité pour protéger les informations sensibles des utilisateurs.

Comment mettre se paramètre dans un code Spring Boot avec une sécurité qui utilise JWT ?

Pour activer la fonctionnalité remember-me dans un projet Spring Boot avec une sécurité basée sur JSON Web Tokens (JWT), vous pouvez utiliser la configuration de Spring Security et ajouter le support pour la fonctionnalité remember-me en utilisant la méthode rememberMe() dans la configuration de votre WebSecurityConfig ou WebSecurityConfigurerAdapter elon votre version de Spirng.

Voici un exemple de code qui montre comment le faire :

version avant Spring boot 2.7

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Autoriser l'accès à certaines ressources publiques sans authentification
        http.authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated();

        // Utiliser JWT pour l'authentification
        http.apply(new JwtSecurityConfigurer(jwtTokenProvider));

        // Activer la fonctionnalité remember-me
        http.rememberMe()
            .key("my-remember-me-key")
            .rememberMeParameter("remember-me")
            .tokenValiditySeconds(86400); // Durée de validité du cookie de mémorisation en milliseconde
    }

    // Autres configurations de sécurité, si nécessaire

}

Dans cet exemple, nous utilisons JwtTokenProvider, qui est une classe personnalisée pour la gestion des JWT dans notre application, pour configurer la sécurité basée sur JWT. Ensuite, nous utilisons la méthode rememberMe() pour activer la fonctionnalité remember-me, et nous définissons plusieurs paramètres, tels que la clé de mémorisation, le nom du paramètre de mémorisation dans la requête et la durée de validité du cookie de mémorisation en secondes (dans cet exemple, 86400 secondes, soit 1 jour).

Version pour Sprng boot 2.7 et ultérieur

@Configuration
public class WebSecurityConfig {

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll()
        .antMatchers("/api/test/**").permitAll()
        .anyRequest().authenticated();
    
    // http....;
    
    return http.build();
  }

Il est important de noter que vous devez également configurer la gestion des utilisateurs et de l’authentification dans votre application, par exemple en utilisant UserDetailsService pour la récupération des informations d’utilisateur, et en configurant les filtres d’authentification appropriés pour vérifier les JWT dans les requêtes entrantes. Assurez-vous également de mettre en place les bonnes pratiques de sécurité pour protéger les informations sensibles, telles que la durée de validité du cookie de mémorisation et les mécanismes de cryptage appropriés.

C’est quoi Authorization et Resource server ?

Dans Spring Security, Authorization Server et Resource Server sont des concepts liés à l’implémentation de l’authentification et de l’autorisation dans une application basée sur Spring Boot.

En utilisant ces deux concepts dans une application basée sur Spring Boot, vous pouvez mettre en place un flux d’authentification et d’autorisation sécurisé pour protéger l’accès aux ressources de votre application. Par exemple, un client (comme une application front-end ou un autre service) peut obtenir un token d’accès auprès de l’Authorization Server après l’authentification réussie de l’utilisateur. Ce token d’accès peut ensuite être utilisé pour accéder aux API protégées du Resource Server, qui vérifiera la validité du token d’accès et les autorisations de l’utilisateur avant de permettre l’accès aux ressources demandées.

Spring Security offre des fonctionnalités intégrées pour implémenter à la fois l’Authorization Server et le Resource Server dans une application Spring Boot, en utilisant des bibliothèques et des configurations spécifiques pour gérer les flux d’authentification et d’autorisation. Par exemple, vous pouvez utiliser les modules spring-security-oauth2 et spring-security-jwt pour implémenter l’Authorization Server et le Resource Server respectivement, en configurant les filtres d’authentification et d’autorisation appropriés dans votre application. Vous pouvez également personnaliser ces configurations pour répondre aux besoins spécifiques de votre application en matière d’authentification et d’autorisation.

Quelle est la différence entre l’authentification et de l’autorisation ?

L’authentification et l’autorisation sont deux concepts clés de la sécurité informatique et sont souvent utilisés ensemble pour garantir la confidentialité, l’intégrité et la disponibilité des données et des ressources.

En résumé, l’authentification est le processus de vérification de l’identité, tandis que l’autorisation est le processus de détermination des droits d’accès en fonction de l’identité authentifiée. L’authentification vérifie “qui vous êtes”, tandis que l’autorisation détermine “ce que vous êtes autorisé à faire”. Les deux concepts sont essentiels pour garantir la sécurité des systèmes informatiques en limitant l’accès aux ressources et aux fonctionnalités aux utilisateurs légitimes et autorisés.

Comment coder cela dans Java Spring Boot ?

Dans une application Java Spring Boot, l’authentification et l’autorisation peuvent être mises en œuvre en utilisant les fonctionnalités de sécurité fournies par le module de sécurité Spring Security.

  1. Authentification : Pour mettre en place l’authentification, vous pouvez configurer Spring Security pour gérer l’authentification des utilisateurs en utilisant diverses méthodes d’authentification telles que la validation des informations d’identification de l’utilisateur par rapport à une base de données, un annuaire LDAP, un fournisseur d’authentification externe comme OAuth, etc. Vous pouvez configurer ces méthodes d’authentification en utilisant des filtres de sécurité et des gestionnaires d’authentification fournis par Spring Security.

Voici un exemple de configuration d’authentification basée sur un formulaire dans un fichier de configuration de sécurité Spring Boot :

(version plus ancienne de Spring)

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
}

Dans cet exemple, configureGlobal configure l’authentification en mémoire avec un utilisateur “user” et un mot de passe “password” avec le rôle “USER”. La méthode configure configure les autorisations pour les différentes URL et définit une page de connexion personnalisée (“/login”). L’annotation @EnableWebSecurity indique que cette classe est une configuration de sécurité pour Spring Boot.

Autorisation : Une fois que l’authentification est en place, vous pouvez configurer les autorisations en utilisant les annotations de sécurité fournies par Spring Security, telles que @PreAuthorize, @PostAuthorize, @Secured, etc. Ces annotations peuvent être utilisées au niveau des méthodes ou des classes pour définir les permissions nécessaires pour accéder à ces méthodes ou classes.

Voici un exemple d’utilisation de l’annotation @PreAuthorize pour définir une autorisation au niveau d’une méthode de contrôleur dans une application Spring Boot :

@RestController
public class UserController {

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/users")
    public List<User> getAllUsers() {
        // Méthode pour récupérer tous les utilisateurs
    }
}

Dans cet exemple, la méthode getAllUsers() du contrôleur UserController est annotée avec @PreAuthorize(“hasRole(‘ADMIN’)”), ce qui signifie que seuls les utilisateurs ayant le rôle ADMIN sont autorisés à accéder à cette méthode.

Ces exemples illustrent comment l’authentification et l’autorisation peuvent être mis en œuvre dans une application Java Spring Boot en utilisant Spring Security. Il existe de nombreuses autres façons de configurer l’authentification et l’autorisation en fonction des besoins spécifiques de l’application, et vous pouvez consulter la documentation officielle de Spring Security pour en savoir plus.

Quelles sont les différences entre spring-security-oauth2 et spring-security-jwt ?

spring-security-oauth2 et spring-security-jwt sont deux bibliothèques différentes de Spring Security qui peuvent être utilisées pour gérer l’authentification et l’autorisation dans une application Java Spring.

Voici quelques différences clés entre les deux :

En résumé, spring-security-oauth2 est une bibliothèque plus complexe et plus puissante qui implémente le protocole d’authentification et d’autorisation OAuth 2.0, tandis que spring-security-jwt se concentre exclusivement sur la gestion des JWT pour l’authentification et l’autorisation, sans inclure les fonctionnalités avancées d’OAuth 2.0. Le choix entre les deux dépend des besoins spécifiques de votre application en termes de flux d’authentification

Quels sont les tiers gratuits pour mettre en place OAuth 2.0 ?

Il existe plusieurs fournisseurs tiers gratuits qui offrent des services d’authentification et d’autorisation basés sur OAuth 2.0. Voici quelques-uns des plus populaires :

Ces fournisseurs tiers offrent des bibliothèques de développement pour faciliter l’intégration d’OAuth 2.0 dans vos applications. Vous pouvez consulter leur documentation respective pour obtenir des informations détaillées sur la manière de mettre en place l’authentification et l’autorisation basées sur OAuth 2.0 avec leurs services.

Comment mettre en place ce tiers sur un serveur ?

Si vous souhaitez mettre en place votre propre serveur d’authentification basé sur OAuth 2.0 sur un serveur quelconque, vous pouvez utiliser des bibliothèques et des frameworks tels que spring-security-oauth2 ou Apache Oltu pour implémenter les spécifications OAuth 2.0 dans votre application Java Spring.

Vous devrez alors gérer les aspects de sécurité, tels que la gestion des jetons d’accès, des rafraîchissements de jetons, des autorisations, etc. Vous pouvez consulter la documentation et les exemples de ces bibliothèques pour apprendre comment mettre en place votre propre serveur OAuth 2.0. Notez que la mise en place d’un serveur d’authentification OAuth 2.0 peut être complexe et nécessite une compréhension approfondie des spécifications OAuth 2.0 et des meilleures pratiques en matière de sécurité.

Exemple simple de mise en place de la sécurité dans Spring Boot expliquée aux enfants !

La sécurité en ligne avec Spring Boot

Salut les enfants ! Aujourd’hui, nous allons parler de la sécurité en ligne avec Spring Boot. Imaginez que vous avez un super jouet, mais vous ne voulez pas que n’importe qui y ait accès, car vous voulez le garder en sécurité. Eh bien, c’est la même chose avec les applications informatiques ! Les applications que nous utilisons sur nos ordinateurs ou nos téléphones ont également besoin de sécurité pour protéger les informations sensibles qu’elles contiennent.

Les bases de la sécurité avec Spring Boot

Maintenant, imaginez que vous avez une boîte secrète pour ranger vos jouets préférés. Cette boîte a une clé spéciale pour l’ouvrir, et seulement les personnes ayant cette clé peuvent y accéder. Eh bien, c’est un peu comme ce que fait Spring Boot pour sécuriser nos applications. Il utilise un système de clés spéciales pour s’assurer que seules les personnes autorisées peuvent accéder à certaines parties de l’application.

L’authentification avec Spring Boot

L’authentification est un moyen de vérifier que quelqu’un est vraiment qui il prétend être. Imaginons que vous ayez une salle de jeux avec un mot de passe pour y entrer. Seules les personnes connaissant ce mot de passe seront autorisées à entrer. Eh bien, c’est ce que fait Spring Boot avec l’authentification. Il vérifie les informations d’identification d’un utilisateur, comme son nom d’utilisateur et son mot de passe, pour s’assurer qu’il est autorisé à accéder à l’application.

L’autorisation avec Spring Boot

Maintenant, imaginez que dans votre salle de jeux, vous avez également différents coins avec des jouets différents. Certains coins sont réservés aux plus grands, tandis que d’autres sont réservés aux plus petits. Eh bien, c’est ce que fait Spring Boot avec l’autorisation. Une fois qu’un utilisateur s’est authentifié avec succès, Spring Boot vérifie également les autorisations de l’utilisateur pour s’assurer qu’il est autorisé à accéder à certaines parties de l’application. Cela permet de garantir que chaque utilisateur ne peut accéder qu’aux parties de l’application qui lui sont autorisées.

Les bonnes pratiques de sécurité avec Spring Boot

En plus de l’authentification et de l’autorisation, Spring Boot offre également d’autres fonctionnalités de sécurité pour protéger nos applications. Par exemple, il peut protéger nos applications contre les attaques malveillantes, comme les attaques par injection de code ou les attaques par déni de service. Spring Boot propose également des fonctionnalités pour sécuriser les communications entre les utilisateurs et l’application en utilisant des protocoles de sécurité comme HTTPS. Il est important de suivre les bonnes pratiques de sécurité avec Spring Boot, comme garder nos bibliothèques à jour, ne pas stocker de mots de passe en clair, et configurer correctement les autorisations d’accès à l’application.

Concepts d’authentification et d’autorisation

Supposons que nous voulions créer une application de jeux en ligne où les utilisateurs peuvent s’inscrire, se connecter et jouer à des jeux. Nous allons créer une API RESTful avec Spring Boot pour gérer ces fonctionnalités.

1) Authentification : Nous allons mettre en place un système d’authentification basé sur les noms d’utilisateur et les mots de passe.

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    // Autres champs et méthodes

    // Getters et Setters
}

2) Autorisation : Nous allons mettre en place un système d’autorisation basé sur les rôles d’utilisateur. Un utilisateur peut être soit un joueur, soit un administrateur.

public enum Role {
    PLAYER, ADMIN
}

@Entity
public class User {
    // Champs existants
    @ElementCollection(fetch = FetchType.EAGER)
    @Enumerated(EnumType.STRING)
    private Set<Role> roles;
    // Autres champs et méthodes

    // Getters et Setters
}

3) Authentification API : Nous allons créer une API REST pour gérer l’authentification des utilisateurs.

@RestController
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
        // Authentification de l'utilisateur
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // Génération du token JWT
        String jwt = jwtTokenProvider.generateToken(authentication);

        // Renvoi du token JWT dans la réponse
        return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
    }
}

4) Autorisation API : Nous allons créer une API REST pour gérer l’autorisation des utilisateurs en fonction de leurs rôles.

@RestController
public class GameController {
    @PreAuthorize("hasRole('PLAYER')")
    @GetMapping("/game")
    public ResponseEntity<String> playGame() {
        // Logique de jeu pour les joueurs autorisés
        return ResponseEntity.ok("Vous pouvez jouer au jeu !");
    }

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin")
    public ResponseEntity<String> adminPage() {
        // Page d'administration pour les administrateurs autorisés
        return ResponseEntity.ok("Vous êtes un administrateur !");
    }
}

Voilà, c’était un exemple simple d’application d’authentification et d’autorisation en utilisant Spring Boot. Bien sûr, dans une vraie application, il faudrait prendre en compte de nombreux autres aspects de sécurité, comme la sécurisation des mots de passe, la protection contre les attaques, etc. Mais j’espère que cela vous donne une idée générale de la façon dont Spring Boot peut être utilisé pour mettre en place la sécurité dans une application.

Partie Front de notre exemple

Voici un exemple simple de code pour la partie front-end de notre application d’authentification et d’autorisation, en utilisant le langage HTML, CSS et JavaScript.

<!DOCTYPE html>
<html>
<head>
    <title>Page de connexion</title>
</head>
<body>
    <h1>Connexion</h1>
    <form onsubmit="login(event)">
        <input type="text" id="username" placeholder="Nom d'utilisateur"><br>
        <input type="password" id="password" placeholder="Mot de passe"><br>
        <input type="submit" value="Se connecter">
    </form>
    <script src="login.js"></script>
</body>
</html>
function login(event) {
    event.preventDefault();
    let username = document.getElementById('username').value;
    let password = document.getElementById('password').value;
    // Appel à l'API REST pour se connecter
    fetch('/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            username: username,
            password: password
        })
    })
    .then(response => response.json())
    .then(data => {
        // Récupération du token JWT depuis la réponse
        let jwt = data.token;
        // Stockage du token JWT dans le local storage
        localStorage.setItem('jwt', jwt);
        // Redirection vers la page d'accueil
        window.location.href = '/home';
    })
    .catch(error => {
        console.error('Erreur de connexion:', error);
        // Affichage d'un message d'erreur
        alert('Nom d\'utilisateur ou mot de passe incorrect');
    });
}
<!DOCTYPE html>
<html>
<head>
    <title>Page d'accueil</title>
</head>
<body>
    <h1>Page d'accueil</h1>
    <div id="content"></div>
    <script src="home.js"></script>
</body>
</html>
let jwt = localStorage.getItem('jwt');

// Appel à l'API REST pour vérifier le rôle de l'utilisateur
fetch('/role', {
    headers: {
        'Authorization': 'Bearer ' + jwt
    }
})
.then(response => response.text())
.then(data => {
    let content = document.getElementById('content');
    if (data === 'PLAYER') {
        content.innerHTML = '<h2>Vous êtes un joueur</h2>';
        // Affichage des fonctionnalités pour les joueurs
    } else if (data === 'ADMIN') {
        content.innerHTML = '<h2>Vous êtes un administrateur</h2>';
        // Affichage des fonctionnalités pour les administrateurs
    } else {
        content.innerHTML = '<h2>Rôle inconnu</h2>';
    }
})
.catch(error => {
    console.error('Erreur de récupération du rôle:', error);
    // Affichage d'un message d'erreur
    alert('Erreur de récupération du rôle');
});

Cela représente une implémentation front-end très basique de notre application d’authentification et d’autorisation.