Spring Security Custom AuthenticationFailureHandler

Spring Security Benutzerdefinierter AuthenticationFailureHandler

1. Überblick

In diesem kurzen Tutorial werden wir veranschaulichen, wie Sie die Behandlung von -Sauthentifizierungsfehlern von Spring Security in einer Spring Boot-Anwendung anpassen. Das Ziel besteht darin, Benutzer mit einemform login-Ansatz. zu authentifizieren

Eine Einführung inSpring Security undForm Login inSpring Boot finden Sie im Artikelthis bzw.this.

2. Authentifizierung und Autorisierung

Authentication undAuthorization werden häufig zusammen verwendet, da sie eine wesentliche und ebenso wichtige Rolle bei der Gewährung des Zugriffs auf das System spielen.

Sie haben jedoch unterschiedliche Bedeutungen und wenden unterschiedliche Einschränkungen an, wenn Sie eine Anfrage validieren:

  • Authentication - VorAuthorization; geht es darum, die empfangenen Anmeldeinformationen zu überprüfen. Hier überprüfen wir, ob sowohl der Benutzername als auch das Passwort mit denen übereinstimmen, die unsere Anwendung erkennt

  • InAuthorizationwird überprüft, ob der erfolgreich authentifizierte Benutzer über Berechtigungen zum Zugriff auf eine bestimmte Funktionalität der Anwendung verfügt

Wir können die Fehlerbehandlung sowohl fürauthenticationals auch fürauthorizationanpassen. In dieser Anwendung konzentrieren wir uns jedoch auf Authentifizierungsfehler.

3. AuthenticationFailureHandler von Spring Security

Spring Security bietet eine Komponente, die standardmäßig Authentifizierungsfehler für uns behandelt.

Es ist jedoch nicht ungewöhnlich, dass wir uns in einem Szenario befinden, in dem das Standardverhalten nicht ausreicht, um die Anforderungen zu erfüllen.

In diesem Fall können wir unsere eigene Komponente erstellen und das gewünschte benutzerdefinierte Verhalten bereitstellen, indem wir dieAuthenticationFailureHandler-Schnittstelle implementieren:

public class CustomAuthenticationFailureHandler
  implements AuthenticationFailureHandler {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void onAuthenticationFailure(
      HttpServletRequest request,
      HttpServletResponse response,
      AuthenticationException exception)
      throws IOException, ServletException {

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        Map data = new HashMap<>();
        data.put(
          "timestamp",
          Calendar.getInstance().getTime());
        data.put(
          "exception",
          exception.getMessage());

        response.getOutputStream()
          .println(objectMapper.writeValueAsString(data));
    }
}

Standardmäßig führtSpringredirectsden Benutzer zurück zur Anmeldeseite, wobeirequest parameter Informationen zum Fehler enthält.

In dieser Anwendung geben wir eine 401-Antwort zurück, die Informationen zum Fehler sowie den Zeitstempel seines Auftretens enthält.

Neben der Standardkomponente hatSpring andere gebrauchsfertige Komponenten, die wir je nach dem, was wir tun möchten, nutzen können:

  • DelegatingAuthenticationFailureHandler delegiertAuthenticationException Unterklassen an verschiedeneAuthenticationFailureHandlers, was bedeutet, dass wir unterschiedliche Verhaltensweisen für verschiedene Instanzen vonAuthenticationException erstellen können

  • ExceptionMappingAuthenticationFailureHandler leitet den Benutzer abhängig vom vollständigen KlassennamenAuthenticationException’s zu einer bestimmten URL weiter

  • ForwardAuthenticationFailureHandler leitet den Benutzer unabhängig vom Typ derAuthenticationException an die angegebene URL weiter

  • SimpleUrlAuthenticationFailureHandler ist die Komponente, die standardmäßig verwendet wird. Sie leitet den Benutzer zu einem angegebenenfailureUrl, if um. Andernfalls wird einfach eine 401-Antwort zurückgegeben

Nachdem wir unsere benutzerdefiniertenAuthenticationFailureHandlererstellt haben, konfigurieren wir unsere Anwendung und überschreiben den Standardhandler vonSpring’s:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration
  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("example")
          .password("example")
          .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http)
      throws Exception {
        http
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .formLogin()
          .failureHandler(customAuthenticationFailureHandler());
    }

    @Bean
    public AuthenticationFailureHandler customAuthenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }
}

Beachten Sie denfailureHandler()-Scall. Hier können wirSpring anweisen, unsere benutzerdefinierte Komponente anstelle der Standardkomponente zu verwenden.

4. Fazit

In diesem Beispiel haben wir den Authentifizierungsfehler-Handler unserer Anwendung mithilfe derSpring’s AuthenticationFailureHandler-Schnittstelle angepasst.

Die Implementierung dieses Beispiels finden Sie inthe Github project.

Wenn Sie lokal ausgeführt werden, können Sie unterlocalhost:8080 auf die Anwendung zugreifen und sie testen