Heim Java javaLernprogramm Implementierung der einmaligen Token-Authentifizierung mit Spring Security

Implementierung der einmaligen Token-Authentifizierung mit Spring Security

Dec 04, 2024 pm 05:11 PM

Implementing One-Time Token Authentication with Spring Security

In der heutigen digitalen Landschaft ist die Bereitstellung sicherer und benutzerfreundlicher Authentifizierungsmethoden von entscheidender Bedeutung. Eine dieser immer beliebter werdenden Methoden ist die One-Time-Token-Authentifizierung (OTT), die oft als „magische Links“ implementiert wird, die per E-Mail verschickt werden. Spring Security 6.4.0 bietet robuste integrierte Unterstützung für die OTT-Authentifizierung, einschließlich gebrauchsfertiger Implementierungen. In diesem umfassenden Leitfaden erfahren Sie, wie Sie eine sichere OTT-Authentifizierung mithilfe integrierter Lösungen und benutzerdefinierter Implementierungen implementieren.

Einmal-Token vs. Einmal-Passwörter verstehen

Bevor wir uns mit der Implementierung befassen, ist es wichtig zu verstehen, dass sich Einmal-Tokens (OTT) von Einmal-Passwörtern (OTP) unterscheiden. Während OTP-Systeme in der Regel eine Ersteinrichtung erfordern und für die Passwortgenerierung auf externe Tools angewiesen sind, sind OTT-Systeme aus Benutzersicht einfacher: Sie erhalten ein eindeutiges Token (normalerweise per E-Mail), mit dem sie sich authentifizieren können.

Zu den wichtigsten Unterschieden gehören:

  • OTT erfordert keine anfängliche Benutzereinrichtung
  • Tokens werden von Ihrer Anwendung generiert und bereitgestellt
  • Jeder Token ist normalerweise für eine einmalige Verwendung gültig und läuft nach einer festgelegten Zeit ab

Verfügbare integrierte Implementierungen

Spring Security bietet zwei Implementierungen von OneTimeTokenService:

  1. InMemoryOneTimeTokenService:

    • Speichert Token im Speicher
    • Ideal für Entwicklung und Tests
    • Nicht für Produktions- oder Clusterumgebungen geeignet
    • Token gehen beim Neustart der Anwendung verloren
  2. JdbcOneTimeTokenService:

    • Speichert Token in einer Datenbank
    • Geeignet für den Produktionseinsatz
    • Funktioniert in Cluster-Umgebungen
    • Persistenter Speicher mit automatischer Bereinigung

Verwenden von InMemoryOneTimeTokenService

So implementieren Sie die einfachere In-Memory-Lösung:

@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();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Verwenden von JdbcOneTimeTokenService

Für Produktionsumgebungen verwenden Sie die JDBC-Implementierung:

@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();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Erforderliche Tabellenstruktur für 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
);
Nach dem Login kopieren

Benutzerdefinierte Implementierung

Für mehr Kontrolle über den Token-Generierungs- und Validierungsprozess können Sie eine benutzerdefinierte Implementierung erstellen:

1. Token-Entität und Repository

@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);
}
Nach dem Login kopieren

2. Benutzerdefinierter Token-Dienst

@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());
    }
}
Nach dem Login kopieren

Implementierung der Token-Lieferung

Spring Security kümmert sich nicht um die Token-Zustellung, daher müssen Sie sie implementieren:

@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);
    }
}
Nach dem Login kopieren

Anpassen von URLs und Seiten

Spring Security bietet mehrere Anpassungsoptionen:

@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();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Produktionsüberlegungen

Beim Einsatz der OTT-Authentifizierung in der Produktion:

  1. Wählen Sie die richtige Implementierung

    • Verwenden Sie JdbcOneTimeTokenService oder eine benutzerdefinierte Implementierung für die Produktion
    • InMemoryOneTimeTokenService sollte nur für Entwicklung/Tests verwendet werden
  2. E-Mail-Zustellung konfigurieren

@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();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
  1. Best Practices für die Sicherheit
    • Legen Sie geeignete Token-Ablaufzeiten fest (15 Minuten empfohlen)
    • Ratenbegrenzung für die Token-Generierung implementieren
    • HTTPS für alle Endpunkte verwenden
    • Überwachen Sie fehlgeschlagene Authentifizierungsversuche
    • Stellen Sie sicher, dass Token nur für den einmaligen Gebrauch bestimmt sind und unmittelbar nach der Verwendung ungültig werden
    • Automatische Bereinigung abgelaufener Token implementieren
    • Verwenden Sie eine sichere zufällige Token-Generierung, um Raten zu verhindern

Wie es funktioniert

  1. Der Benutzer fordert ein Token an, indem er seine E-Mail-Adresse übermittelt
  2. Das System generiert ein sicheres Token und sendet einen magischen Link per E-Mail
  3. Der Benutzer klickt auf den Link und wird zur Seite zur Token-Übermittlung weitergeleitet
  4. Das System validiert das Token und authentifiziert den Benutzer, wenn es gültig ist

Abschluss

Die OTT-Unterstützung von Spring Security bietet eine solide Grundlage für die Implementierung einer sicheren, benutzerfreundlichen Authentifizierung. Unabhängig davon, ob Sie sich für die integrierten Implementierungen entscheiden oder eine benutzerdefinierte Lösung erstellen, können Sie Ihren Benutzern eine passwortlose Anmeldeoption anbieten und gleichzeitig hohe Sicherheitsstandards einhalten.

Denken Sie bei der Implementierung der OTT-Authentifizierung an Folgendes:

  • Wählen Sie die passende Implementierung für Ihre Umgebung
  • Implementieren Sie eine sichere Token-Zustellung
  • Konfigurieren Sie den ordnungsgemäßen Ablauf des Tokens
  • Befolgen Sie die Best Practices für die Sicherheit
  • Erstellen Sie eine benutzerfreundliche Fehlerbehandlung und Weiterleitungen
  • Implementieren Sie geeignete E-Mail-Vorlagen für ein professionelles Erscheinungsbild

Indem Sie diesem Leitfaden folgen, können Sie ein sicheres und benutzerfreundliches OTT-Authentifizierungssystem implementieren, das die Anforderungen Ihrer Anwendung erfüllt und gleichzeitig die robusten Sicherheitsfunktionen von Spring Security nutzt.

Referenz: https://docs.spring.io/spring-security/reference/servlet/authentication/onetimetoken.html

Das obige ist der detaillierte Inhalt vonImplementierung der einmaligen Token-Authentifizierung mit Spring Security. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Top 4 JavaScript -Frameworks in 2025: React, Angular, Vue, Svelte Top 4 JavaScript -Frameworks in 2025: React, Angular, Vue, Svelte Mar 07, 2025 pm 06:09 PM

Top 4 JavaScript -Frameworks in 2025: React, Angular, Vue, Svelte

Wie implementiere ich mehrstufige Caching in Java-Anwendungen mit Bibliotheken wie Koffein oder Guava-Cache? Wie implementiere ich mehrstufige Caching in Java-Anwendungen mit Bibliotheken wie Koffein oder Guava-Cache? Mar 17, 2025 pm 05:44 PM

Wie implementiere ich mehrstufige Caching in Java-Anwendungen mit Bibliotheken wie Koffein oder Guava-Cache?

Node.js 20: wichtige Leistungssteigerung und neue Funktionen Node.js 20: wichtige Leistungssteigerung und neue Funktionen Mar 07, 2025 pm 06:12 PM

Node.js 20: wichtige Leistungssteigerung und neue Funktionen

Wie funktioniert der Klassenladungsmechanismus von Java, einschließlich verschiedener Klassenloader und deren Delegationsmodelle? Wie funktioniert der Klassenladungsmechanismus von Java, einschließlich verschiedener Klassenloader und deren Delegationsmodelle? Mar 17, 2025 pm 05:35 PM

Wie funktioniert der Klassenladungsmechanismus von Java, einschließlich verschiedener Klassenloader und deren Delegationsmodelle?

ICEBERG: Die Zukunft von Data Lake Tabellen ICEBERG: Die Zukunft von Data Lake Tabellen Mar 07, 2025 pm 06:31 PM

ICEBERG: Die Zukunft von Data Lake Tabellen

Spring Boot Snakeyaml 2.0 CVE-2022-1471 Problem behoben Spring Boot Snakeyaml 2.0 CVE-2022-1471 Problem behoben Mar 07, 2025 pm 05:52 PM

Spring Boot Snakeyaml 2.0 CVE-2022-1471 Problem behoben

Wie kann ich JPA (Java Persistence-API) für Objektrelationszuordnungen mit erweiterten Funktionen wie Caching und faulen Laden verwenden? Wie kann ich JPA (Java Persistence-API) für Objektrelationszuordnungen mit erweiterten Funktionen wie Caching und faulen Laden verwenden? Mar 17, 2025 pm 05:43 PM

Wie kann ich JPA (Java Persistence-API) für Objektrelationszuordnungen mit erweiterten Funktionen wie Caching und faulen Laden verwenden?

Wie benutze ich Maven oder Gradle für das fortschrittliche Java -Projektmanagement, die Erstellung von Automatisierung und Abhängigkeitslösung? Wie benutze ich Maven oder Gradle für das fortschrittliche Java -Projektmanagement, die Erstellung von Automatisierung und Abhängigkeitslösung? Mar 17, 2025 pm 05:46 PM

Wie benutze ich Maven oder Gradle für das fortschrittliche Java -Projektmanagement, die Erstellung von Automatisierung und Abhängigkeitslösung?

See all articles