Ein benutzerdefinierter Spring SecurityConfigurer

Ein Custom Spring SecurityConfigurer

1. Überblick

Die Java-Konfigurationsunterstützung von Spring Security bietet uns leistungsstarke, flüssige APIs, mit denen Sicherheitszuordnungen und -regeln für eine Anwendung definiert werden können.

In diesem kurzen Artikel werden wir sehen, wie wir diesen einen Schritt nach vorne machen und tatsächlich einen benutzerdefinierten Konfigurator definieren können. this is an advanced and flexible way to introduce custom logic into a standard security configuration.

In unserem kurzen Beispiel hier fügen wir Funktionen hinzu, die Fehler für authentifizierte Benutzer in Abhängigkeit von einer bestimmten Liste von Fehlerstatuscodes protokollieren.

2. Ein benutzerdefiniertesSecurityConfigurer

Um unseren Konfigurator zu definieren, müssen Sie zuerstwe need to extend the AbstractHttpConfigurer class:

public class ClientErrorLoggingConfigurer
  extends AbstractHttpConfigurer {

    private List errorCodes;

    // standard constructors

    @Override
    public void init(HttpSecurity http) throws Exception {
        // initialization code
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
       http.addFilterAfter(
         new ClientErrorLoggingFilter(errorCodes),
         FilterSecurityInterceptor.class);
    }
}

Hierthe main method we need to override is the configure() method - enthält die Sicherheitskonfiguration, auf die dieser Konfigurator angewendet wird.

In unserem Beispiel haben wir nach dem letzten Spring Security-Filter einen neuen Filter registriert. Da wir beabsichtigen, Fehlercodes für den Antwortstatus zu protokollieren, haben wir eineerrorCodes List-Eigenschaft hinzugefügt, mit der wir die zu protokollierenden Fehlercodes steuern können.

Optional können wir derinit()-Methode, die vor derconfigure()-Methode ausgeführt wird, eine zusätzliche Konfiguration hinzufügen.

Definieren wir als Nächstes die Spring Security-Filterklasse, die wir in unserer benutzerdefinierten Implementierung registrieren:

public class ClientErrorLoggingFilter extends GenericFilterBean {

    private static final Logger logger = LogManager.getLogger(
      ClientErrorLoggingFilter.class);
    private List errorCodes;

    // standard constructor

    @Override
    public void doFilter(
      ServletRequest request,
      ServletResponse response,
      FilterChain chain)
      throws IOException, ServletException {
        //...

        chain.doFilter(request, response);
    }
}

Dies ist eine Standard-Spring-Filterklasse, dieGenericFilterBean erweitert und die MethodedoFilter() überschreibt. Es verfügt über zwei Eigenschaften, die den Logger darstellen, mit dem Nachrichten angezeigt werden, und dieList vonerrorCodes.

Schauen wir uns die MethodedoFilter()genauer an:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
    chain.doFilter(request, response);
    return;
}
int status = ((HttpServletResponse) response).getStatus();
if (status < 400 || status >= 500) {
    chain.doFilter(request, response);
    return;
}
if (errorCodes == null) {
    logger.debug("User " + auth.getName() + " encountered error " + status);
} else {
    if (errorCodes.stream().anyMatch(s -> s.value() == status)) {
        logger.debug("User " + auth.getName() + " encountered error " + status);
    }
}

Wenn es sich bei dem Statuscode um einen Clientfehlerstatuscode handelt, der zwischen 400 und 500 liegt, überprüfen wir die ListeerrorCodes.

Wenn dies leer ist, wird jeder Clientfehlerstatuscode angezeigt. Andernfalls prüfen wir zunächst, ob der Fehlercode Teil der angegebenenList der Statuscodes ist.

3. Verwenden des benutzerdefinierten Konfigurators

Jetzt, da wir unsere benutzerdefinierte API haben,we can add it to the Spring Security configuration by defining the bean, then by using the apply() method vonHttpSecurity:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          //...
          .and()
          .apply(clientErrorLogging());
    }

    @Bean
    public ClientErrorLoggingConfigurer clientErrorLogging() {
        return new ClientErrorLoggingConfigurer() ;
    }
}

Wir können die Bean auch mit einer bestimmten Liste von Fehlercodes definieren, die protokolliert werden sollen:

@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
    return new ClientErrorLoggingConfigurer(Arrays.asList(HttpStatus.NOT_FOUND)) ;
}

Und das ist alles! Jetzt enthält unsere Sicherheitskonfiguration den benutzerdefinierten Filter und zeigt die Protokollmeldungen an.

Wenn der benutzerdefinierte Konfigurator standardmäßig hinzugefügt werden soll, können wir die DateiMETA-INF/spring.factoriesverwenden:

org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.example.dsl.ClientErrorLoggingConfigurer

Und um es manuell zu deaktivieren, können wir dann diedisable()-Methode verwenden:

//...
.apply(clientErrorLogging()).disable();

4. Fazit

In diesem kurzen Tutorial haben wir uns auf eine erweiterte Funktion der Spring Security-Konfigurationsunterstützung konzentriert -we’ve seen how to define our own, custom SecurityConfigurer.

Wie immer kann der vollständige Quellcode des Beispielsover on GitHub gefunden werden.