Maison > Java > javaDidacticiel > Système de connexion avec jeton JWT et mot de passe de réinitialisation par e-mail

Système de connexion avec jeton JWT et mot de passe de réinitialisation par e-mail

Barbara Streisand
Libérer: 2024-11-24 22:48:13
original
377 Les gens l'ont consulté

Login system with JWT token and email reset password

Introduction

L'Application Spring Login est un système de gestion des utilisateurs sécurisé et robuste construit à l'aide de Spring Boot. Ce projet démontre des approches modernes pour mettre en œuvre des fonctionnalités d'authentification, d'autorisation et de compte utilisateur. Les fonctionnalités clés incluent l'enregistrement des utilisateurs, la gestion sécurisée des mots de passe avec BCrypt, la réinitialisation du mot de passe par courrier électronique et l'authentification JWT (JSON Web Token). Conçue dans un souci d'extensibilité et d'évolutivité, cette application constitue une excellente base pour les projets nécessitant une gestion des utilisateurs et un contrôle d'accès basé sur les rôles.

En tirant parti des outils puissants de Spring tels que Spring Security, Spring Data JPA et JavaMailSender, ce projet garantit les meilleures pratiques en matière de sécurité, de maintenabilité et de facilité. d’intégration. Que vous construisiez une petite application Web ou un système de grande entreprise, ce projet fournit un point de départ pratique et bien structuré pour gérer les comptes d'utilisateurs en toute sécurité.


Configuration

Dépendances Pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Docker

Pour exécuter la base de données PostgreSQL, créez un fichier docker-compose.yaml :

services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Exécuter :

docker compose up -d
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

application.propriétés

spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

env.propriétés

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Comment créer une clé asymétrique ?

Voir dans cet article comment générer des clés asymétriques


Structure du projet

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Caractéristiques

  • Inscription de l'utilisateur avec validation email et mot de passe
  • Connectez-vous avec l'authentification JWT
  • Récupération de mot de passe avec envoi d'un lien par e-mail
  • Réinitialisation du mot de passe via un lien avec un jeton temporaire
  • Validation sur le terrain et gestion des erreurs

Code

Répertoire de configuration

BCryptPasswordConfig.java

package dev.mspilari.login_app.configs;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class BCryptPasswordConfig {

    @Bean
    public BCryptPasswordEncoder bPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Copier après la connexion
Copier après la connexion
Copier après la connexion

Répartition des codes

  1. @Configuration

    • Cette annotation indique à Spring que la classe contient des définitions de bean.
    • Les classes annotées avec @Configuration sont traitées lors du démarrage de l'application, et toutes les méthodes annotées avec @Bean verront leurs valeurs de retour ajoutées au contexte de l'application Spring en tant que beans gérés.
  2. @Bean

    • L'annotation @Bean sur la méthode bPasswordEncoder() indique que cette méthode renvoie un objet qui doit être enregistré en tant que bean dans le contexte de l'application Spring.
    • Cela permet à l'objet BCryptPasswordEncoder d'être injecté partout où il est nécessaire dans l'application.
  3. BCryptPasswordEncoder

    • Il s'agit d'une classe utilitaire fournie par Spring Security pour coder les mots de passe.
    • Il utilise l'algorithme de hachage BCrypt, qui est considéré comme un moyen solide et sécurisé de hacher des mots de passe. L'algorithme ajoute automatiquement un « sel » au mot de passe avant le hachage, le rendant résistant aux attaques par dictionnaire et aux attaques par table arc-en-ciel.
  4. Méthode bPasswordEncoder()

    • Lorsque cette méthode est appelée par le framework Spring, elle crée une nouvelle instance de BCryptPasswordEncoder et la rend disponible dans le contexte de l'application.
    • D'autres classes de l'application peuvent ensuite câbler automatiquement ce bean pour encoder ou faire correspondre les mots de passe.

JwtConfig.java

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Répartition des codes

1. Annotations au niveau de la classe

services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Indique qu'il s'agit d'une classe de configuration Spring où les beans (composants gérés par Spring) sont définis.
  • Les beans définis ici seront disponibles dans le contexte d'application Spring pour l'injection de dépendances.

2. Injection de clés RSA depuis la configuration

docker compose up -d
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • @Value est utilisé pour injecter la clé publique et la clé privée à partir du fichier de propriétés de l'application (par exemple, application.yml ou application.properties).
  • Ces clés devraient se trouver dans les propriétés comme :
spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

3. Haricots d'encodeur JWT

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Objectif : crée un bean pour encoder (générer) des jetons JWT.
  • Étapes :
    1. Construire la clé RSA :
      • RSAKey.Builder crée une représentation JWK (JSON Web Key) de la paire de clés RSA publique/privée.
    2. Créer un ensemble JWK :
      • ImmutableJWKSet stocke la clé dans un ensemble. Cet ensemble est utilisé par les bibliothèques Nimbus JOSE pour signer des jetons.
    3. NimbusJwtEncoder :
      • Cet encodeur utilise ImmutableJWKSet pour encoder et signer des jetons à l'aide de la clé privée.

4. Haricot décodeur JWT

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Objectif : crée un bean pour décoder et vérifier les jetons JWT.
  • Étapes :
    1. Vérification de la clé publique :
      • NimbusJwtDecoder.withPublicKey() est configuré avec la clé publique RSA. Il vérifie la signature des jetons.
    2. Construire un décodeur :
      • La méthode build() crée l'instance du décodeur.

Comment fonctionnent l'encodage et le décodage JWT

  1. Encodage JWT (génération de jetons) :

    • Le bean JwtEncoder est utilisé pour créer un jeton JWT signé. Ce jeton contient généralement des informations utilisateur (par exemple, nom d'utilisateur, rôles, etc.) sous forme de revendications et est signé à l'aide de la clé privée RSA.
    • Exemple :
    package dev.mspilari.login_app.configs;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    @Configuration
    public class BCryptPasswordConfig {
    
        @Bean
        public BCryptPasswordEncoder bPasswordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
    
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
  2. Décodage JWT (vérification du jeton) :

    • Le bean JwtDecoder est utilisé pour décoder et vérifier le jeton à l'aide de la clé publique RSA. Cela garantit que le jeton :
      • A été émis par le serveur (vérification de la signature).
      • N'a pas été altéré.
    • Exemple :
    package dev.mspilari.login_app.configs;
    
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.oauth2.jwt.JwtDecoder;
    import org.springframework.security.oauth2.jwt.JwtEncoder;
    import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
    import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
    
    import com.nimbusds.jose.jwk.JWKSet;
    import com.nimbusds.jose.jwk.RSAKey;
    import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
    
    @Configuration
    public class JwtConfig {
        @Value("${jwt.public.key}")
        private RSAPublicKey publicKey;
    
        @Value("${jwt.private.key}")
        private RSAPrivateKey privateKey;
    
        @Bean
        public JwtEncoder jwtEncoder() {
            var jwk = new RSAKey.Builder(this.publicKey).privateKey(this.privateKey).build();
    
            var jwks = new ImmutableJWKSet<>(new JWKSet(jwk));
    
            return new NimbusJwtEncoder(jwks);
        }
    
        @Bean
        public JwtDecoder jwtDecoder() {
            return NimbusJwtDecoder.withPublicKey(this.publicKey).build();
        }
    }
    
    Copier après la connexion
    Copier après la connexion

SecurityConfig.java

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

1. Annotations au niveau de la classe

services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • @Configuration : marque cette classe comme une configuration Spring qui définit les beans.
  • @EnableWebSecurity : active les fonctionnalités de sécurité Web de Spring Security.
  • @EnableMethodSecurity : active les annotations de sécurité au niveau de la méthode comme @PreAuthorize ou @Secured. Cela vous permet de contrôler l'accès à des méthodes spécifiques dans votre application en fonction de rôles, d'autorisations ou de conditions.

2. Haricot SecurityFilterChain

docker compose up -d
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Définit la chaîne de filtres de sécurité pour l'application. Une chaîne de filtres est une séquence de filtres de sécurité appliqués aux requêtes HTTP entrantes.

3. Protection CSRF

spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • La protection CSRF (Cross-Site Request Forgery) est désactivée.
    • La protection CSRF est souvent inutile pour les API sans état, car les jetons (comme JWT) fournissent déjà un moyen d'empêcher les requêtes non autorisées.
    • La désactivation simplifie la configuration de la sécurité pour cette API basée sur JWT.

4. Règles d'autorisation

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Configure les points de terminaison qui nécessitent une authentification :
    • Autoriser tout :
    • Les requêtes POST vers des points de terminaison tels que /user/register, /user/login, /user/redeem-password et /user/reset-password sont ouvertes à tous (aucune authentification requise).
    • Ces points de terminaison sont probablement utilisés pour l'enregistrement des utilisateurs, la connexion et la récupération/réinitialisation du mot de passe, qui sont généralement accessibles sans connexion.
    • Authentifier les autres demandes :
    • Tous les autres points de terminaison (anyRequest) nécessitent une authentification.

5. Validation JWT

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Configure l'application en tant que serveur de ressources OAuth 2.0 qui valide les requêtes à l'aide de jetons JWT.
  • Décodeur JWT :
    • Le bean JwtDecoder (fourni par JwtConfig) est utilisé pour vérifier les jetons JWT entrants pour les demandes visant à sécuriser les points de terminaison.

Comment cela fonctionne

  1. CSRF désactivé : puisqu'il s'agit d'une API reposant sur l'authentification JWT sans état, la désactivation de CSRF est une pratique courante.
  2. Règles d'autorisation :
    • Les utilisateurs non authentifiés ne peuvent accéder qu'aux points de terminaison explicitement autorisés (par exemple, /user/register ou /user/login).
    • Toute autre demande nécessite un jeton JWT valide.
  3. Validation JWT :
    • Spring Security extrait automatiquement l'en-tête Authorization des requêtes entrantes.
    • Si l'en-tête contient un jeton JWT valide, la demande est authentifiée et le contexte utilisateur est établi.
    • Si le token est invalide ou manquant, la demande est rejetée.

Répertoire des domaines

Annuaire de courrier électronique

Répertoire des services
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Annuaire des utilisateurs

Répertoire des contrôleurs
services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Répertoire DTO

UtilisateurDto.java

docker compose up -d
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

UserRedeemPasswordDto.java

spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key

Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

UserResetPasswordDto.java

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Répertoire des entités

UserEntity.java

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Répertoire des énumérations

Rôle.java

package dev.mspilari.login_app.configs;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class BCryptPasswordConfig {

    @Bean
    public BCryptPasswordEncoder bPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Copier après la connexion
Copier après la connexion
Copier après la connexion

Répertoire des référentiels

UserRepository.java

package dev.mspilari.login_app.configs;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;

@Configuration
public class JwtConfig {
    @Value("${jwt.public.key}")
    private RSAPublicKey publicKey;

    @Value("${jwt.private.key}")
    private RSAPrivateKey privateKey;

    @Bean
    public JwtEncoder jwtEncoder() {
        var jwk = new RSAKey.Builder(this.publicKey).privateKey(this.privateKey).build();

        var jwks = new ImmutableJWKSet<>(new JWKSet(jwk));

        return new NimbusJwtEncoder(jwks);
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withPublicKey(this.publicKey).build();
    }
}
Copier après la connexion
Copier après la connexion

Répertoire des services

UserService.java

@Configuration
Copier après la connexion

Répertoire des exceptions

GlobalException.java

@Value("${jwt.public.key}")
private RSAPublicKey publicKey;

@Value("${jwt.private.key}")
private RSAPrivateKey privateKey;
Copier après la connexion

Répertoire utilitaires

JwtActions.java

  jwt.public.key=<your-public-key>
  jwt.private.key=<your-private-key>
Copier après la connexion

Conclusion

Dans ce projet, nous avons mis en œuvre avec succès un système d'authentification utilisateur sécurisé et riche en fonctionnalités à l'aide de Spring Boot. Au-delà des fonctionnalités de base telles que l'enregistrement des utilisateurs, la connexion et l'authentification basée sur JWT, l'application intègre également un système de récupération de mot de passe. Les utilisateurs peuvent réinitialiser leurs mots de passe via un lien e-mail, garantissant ainsi un processus de récupération fluide et sécurisé.

Pour faciliter la récupération de mot de passe par courrier électronique, nous avons intégré Spring Email avec Mailtrap, un service de test de courrier électronique sûr et efficace. Cela permet à l'application d'envoyer des liens de réinitialisation de mot de passe avec des jetons temporaires tout en garantissant que les e-mails sont envoyés en toute sécurité et testés dans un environnement contrôlé. Cette configuration montre comment gérer des flux de travail sensibles tels que la récupération de mot de passe sans exposer les utilisateurs réels à des problèmes potentiels pendant le développement et les tests.

La combinaison de pratiques d'authentification sécurisées, d'une gestion robuste des mots de passe et d'une intégration transparente de la messagerie électronique fait de cette application une base fiable pour tout système Web moderne. Les développeurs peuvent adapter ces pratiques en fonction de leurs besoins spécifiques, garantissant à la fois l'évolutivité et la confiance des utilisateurs. En tirant parti des meilleures pratiques et d'outils tels que Spring Security et Mailtrap, nous avons démontré comment créer facilement des applications sécurisées et centrées sur l'utilisateur.


? Référence

  • Sécurité du printemps
  • MailTrap
  • E-mail de printemps

? Référentiel de projet

  • Référentiel de projet sur Github

? Parle moi

  • LinkedIn
  • Github
  • Portefeuille

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal