


Implémentation de l'authentification par jeton unique avec Spring Security
Dans le paysage numérique actuel, il est crucial de fournir des méthodes d'authentification sécurisées et conviviales. L'une de ces méthodes qui gagne en popularité est l'authentification One-Time Token (OTT), souvent mise en œuvre sous forme de « liens magiques » envoyés par courrier électronique. Spring Security 6.4.0 offre une prise en charge intégrée robuste de l'authentification OTT, y compris des implémentations prêtes à l'emploi. Dans ce guide complet, nous explorerons comment mettre en œuvre une authentification OTT sécurisée à l'aide de solutions intégrées et d'implémentations personnalisées.
Comprendre les jetons à usage unique et les mots de passe à usage unique
Avant de plonger dans la mise en œuvre, il est important de comprendre que les jetons à usage unique (OTT) diffèrent des mots de passe à usage unique (OTP). Alors que les systèmes OTP nécessitent généralement une configuration initiale et s'appuient sur des outils externes pour la génération de mots de passe, les systèmes OTT sont plus simples du point de vue de l'utilisateur : ils reçoivent un jeton unique (généralement par e-mail) qu'ils peuvent utiliser pour s'authentifier.
Les principales différences incluent :
- OTT ne nécessite pas de configuration initiale de l'utilisateur
- Les jetons sont générés et délivrés par votre application
- Chaque jeton est généralement valable pour un usage unique et expire après une durée définie
Implémentations intégrées disponibles
Spring Security fournit deux implémentations de OneTimeTokenService :
-
InMemoryOneTimeTokenService :
- Stocke les jetons en mémoire
- Idéal pour le développement et les tests
- Ne convient pas aux environnements de production ou en cluster
- Les jetons sont perdus au redémarrage de l'application
-
JdbcOneTimeTokenService :
- Stocke les jetons dans une base de données
- Convient à une utilisation en production
- Fonctionne dans des environnements en cluster
- Stockage persistant avec nettoyage automatique
Utilisation d'InMemoryOneTimeTokenService
Voici comment implémenter la solution en mémoire la plus simple :
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login/**", "/ott/**").permitAll() .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()) .oneTimeTokenLogin(Customizer.withDefaults()); // Uses InMemoryOneTimeTokenService by default return http.build(); } }
Utilisation de JdbcOneTimeTokenService
Pour les environnements de production, utilisez l'implémentation JDBC :
@Configuration @EnableWebSecurity public class SecurityConfig { @Autowired JdbcTemplate jdbcTemplate; @Bean public OneTimeTokenService oneTimeTokenService() { return new JdbcOneTimeTokenService(jdbcTemplate); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login/**", "/ott/**").permitAll() .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()) .oneTimeTokenLogin(Customizer.withDefaults()); return http.build(); } }
Structure de table requise pour JdbcOneTimeTokenService :
CREATE TABLE one_time_tokens ( token_value VARCHAR(255) PRIMARY KEY, username VARCHAR(255) NOT NULL, issued_at TIMESTAMP NOT NULL, expires_at TIMESTAMP NOT NULL, used BOOLEAN NOT NULL );
Implémentation personnalisée
Pour plus de contrôle sur le processus de génération et de validation des jetons, vous pouvez créer une implémentation personnalisée :
1. Entité de jeton et référentiel
@Entity @Table(name = "one_time_tokens") public class OneTimeToken { @Id @GeneratedValue private Long id; private String tokenValue; private String username; private LocalDateTime createdAt; private LocalDateTime expiresAt; private boolean used; // Getters and setters omitted for brevity } @Repository public interface OneTimeTokenRepository extends JpaRepository<OneTimeToken, Long> { Optional<OneTimeToken> findByTokenValueAndUsedFalse(String tokenValue); void deleteByExpiresAtBefore(LocalDateTime dateTime); }
2. Service de jetons personnalisés
@Service @Transactional public class PersistentOneTimeTokenService implements OneTimeTokenService { private static final int TOKEN_VALIDITY_MINUTES = 15; @Autowired private OneTimeTokenRepository tokenRepository; @Override public OneTimeToken generate(GenerateOneTimeTokenRequest request) { String tokenValue = UUID.randomUUID().toString(); LocalDateTime now = LocalDateTime.now(); OneTimeToken token = new OneTimeToken(); token.setTokenValue(tokenValue); token.setUsername(request.getUsername()); token.setCreatedAt(now); token.setExpiresAt(now.plusMinutes(TOKEN_VALIDITY_MINUTES)); token.setUsed(false); return return new DefaultOneTimeToken(token.getTokenValue(),token.getUsername(), Instant.now()); } @Override public Authentication consume(ConsumeOneTimeTokenRequest request) { OneTimeToken token = tokenRepository.findByTokenValueAndUsedFalse(request.getTokenValue()) .orElseThrow(() -> new BadCredentialsException("Invalid or expired token")); if (token.getExpiresAt().isBefore(LocalDateTime.now())) { throw new BadCredentialsException("Token has expired"); } token.setUsed(true); tokenRepository.save(token); UserDetails userDetails = loadUserByUsername(token.getUsername()); return new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); } }
Implémentation de la livraison de jetons
Spring Security ne gère pas la livraison des jetons, vous devrez donc l'implémenter :
@Component public class EmailMagicLinkHandler implements OneTimeTokenGenerationSuccessHandler { @Autowired private JavaMailSender mailSender; private final OneTimeTokenGenerationSuccessHandler redirectHandler = new RedirectOneTimeTokenGenerationSuccessHandler("/ott/check-email"); @Override public void handle(HttpServletRequest request, HttpServletResponse response, OneTimeToken token) throws IOException, ServletException { String magicLink = UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request)) .replacePath(request.getContextPath()) .replaceQuery(null) .fragment(null) .path("/login/ott") .queryParam("token", token.getTokenValue()) .toUriString(); SimpleMailMessage message = new SimpleMailMessage(); message.setTo(getUserEmail(token.getUsername())); message.setSubject("Your Sign-in Link"); message.setText("Click here to sign in: " + magicLink); mailSender.send(message); redirectHandler.handle(request, response, token); } }
Personnalisation des URL et des pages
Spring Security propose plusieurs options de personnalisation :
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login/**", "/ott/**").permitAll() .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()) .oneTimeTokenLogin(Customizer.withDefaults()); // Uses InMemoryOneTimeTokenService by default return http.build(); } }
Considérations relatives à la production
Lors du déploiement de l'authentification OTT en production :
-
Choisissez la bonne mise en œuvre
- Utilisez JdbcOneTimeTokenService ou une implémentation personnalisée pour la production
- InMemoryOneTimeTokenService ne doit être utilisé que pour le développement/test
Configurer la livraison des e-mails
@Configuration @EnableWebSecurity public class SecurityConfig { @Autowired JdbcTemplate jdbcTemplate; @Bean public OneTimeTokenService oneTimeTokenService() { return new JdbcOneTimeTokenService(jdbcTemplate); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login/**", "/ott/**").permitAll() .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()) .oneTimeTokenLogin(Customizer.withDefaults()); return http.build(); } }
-
Bonnes pratiques de sécurité
- Définissez les délais d'expiration des jetons appropriés (15 minutes recommandées)
- Implémenter une limitation de débit pour la génération de jetons
- Utilisez HTTPS pour tous les points de terminaison
- Surveiller les tentatives d'authentification ayant échoué
- Assurez-vous que les jetons sont à usage unique et invalidés immédiatement après utilisation
- Mettre en œuvre le nettoyage automatique des jetons expirés
- Utilisez la génération sécurisée de jetons aléatoires pour éviter les devinettes
Comment ça marche
- L'utilisateur demande un jeton en soumettant son adresse e-mail
- Le système génère un jeton sécurisé et envoie un lien magique par e-mail
- L'utilisateur clique sur le lien et est redirigé vers la page de soumission de jetons
- Le système valide le token et authentifie l'utilisateur s'il est valide
Conclusion
La prise en charge OTT de Spring Security fournit une base solide pour la mise en œuvre d'une authentification sécurisée et conviviale. Que vous choisissiez les implémentations intégrées ou créiez une solution personnalisée, vous pouvez offrir à vos utilisateurs une option de connexion sans mot de passe tout en maintenant des normes de sécurité élevées.
Lors de la mise en œuvre de l'authentification OTT, n'oubliez pas de :
- Choisissez l'implémentation appropriée pour votre environnement
- Mettre en œuvre la livraison sécurisée de jetons
- Configurer l'expiration appropriée du jeton
- Suivez les meilleures pratiques de sécurité
- Créez une gestion des erreurs et des redirections conviviales
- Implémentez des modèles d'e-mails appropriés pour un look professionnel
En suivant ce guide, vous pouvez mettre en œuvre un système d'authentification OTT sécurisé et convivial qui répond aux besoins de votre application tout en tirant parti des fonctionnalités de sécurité robustes de Spring Security.
Référence : https://docs.spring.io/spring-security/reference/servlet/authentication/onetimetoken.html
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Top 4 frameworks JavaScript en 2025: React, Angular, Vue, Svelte

Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave?

Node.js 20: Boosts de performances clés et nouvelles fonctionnalités

Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation?

Iceberg: L'avenir des tables de Data Lake

Spring Boot SnakeyAml 2.0 CVE-2022-1471 Issue fixe

Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux?

Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance?
