1. Overview
1.概述
The Spring Security Java configuration support provides us with a powerful fluent APIs – to define security mappings and rules for an application.
Spring Security的Java配置支持为我们提供了一个强大的流畅的API–为应用程序定义安全映射和规则。
In this quick article, we’ll see how we can take this one step forward and actually define a custom configurer; this is an advanced and flexible way to introduce custom logic into a standard security configuration.
在这篇简短的文章中,我们将看到我们如何向前迈出一步,并实际定义一个自定义的配置器;这是一种先进而灵活的方式,可以将自定义逻辑引入标准安全配置中。
For our quick example here, we’ll add functionality that logs errors for authenticated users depending on a given list of error status codes.
对于我们这里的快速例子,我们将添加功能,根据给定的错误状态代码列表,为认证用户记录错误。
2. A Custom SecurityConfigurer
2.一个自定义的SecurityConfigurer
To start defining our configurer, first we need to extend the AbstractHttpConfigurer class:
要开始定义我们的配置器,首先我们需要扩展AbstractHttpConfigurer类。
public class ClientErrorLoggingConfigurer
extends AbstractHttpConfigurer<ClientErrorLoggingConfigurer, HttpSecurity> {
private List<HttpStatus> 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);
}
}
Here, the main method we need to override is the configure() method – which contains the security configuration that this configurer will apply to.
在这里,我们需要覆盖的主要方法是configure()方法–它包含本配置器将应用的安全配置。
In our example, we’ve registered a new filter after the last Spring Security filter. Also, since we intend to log response status error codes, we’ve added an errorCodes List property that we can use to control the error codes that we’ll log.
在我们的例子中,我们在最后一个Spring Security过滤器之后注册了一个新的过滤器。此外,由于我们打算记录响应状态的错误代码,我们添加了一个errorCodes List属性,我们可以用它来控制我们要记录的错误代码。
We can also optionally add additional configuration in the init() method, which is executed before the configure() method.
我们也可以选择在init()方法中添加额外的配置,该方法在configure()方法之前执行。
Next, let’s define the Spring Security filter class that we register in our custom implementation:
接下来,让我们定义一下我们在自定义实现中注册的Spring Security过滤器类。
public class ClientErrorLoggingFilter extends GenericFilterBean {
private static final Logger logger = LogManager.getLogger(
ClientErrorLoggingFilter.class);
private List<HttpStatus> errorCodes;
// standard constructor
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
//...
chain.doFilter(request, response);
}
}
This is a standard Spring filter class which extends GenericFilterBean and overrides the doFilter() method. It has two properties representing the logger we’ll use to display messages and the List of errorCodes.
这是一个标准的Spring过滤器类,它扩展了GenericFilterBean并重写了doFilter()方法。它有两个属性,分别代表我们用来显示消息的记录器和List的errorCodes。
Let’s take a closer look at the doFilter() method:
让我们仔细看看doFilter()方法。
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);
}
}
If the status code is a client error status code, meaning between 400 and 500, then we’ll check the errorCodes list.
如果状态码是客户错误状态码,即在400和500之间,那么我们将检查errorCodes列表。
If this is empty, then we’ll display any client error status code. Otherwise, we’ll first check if the error code is part of the given List of status codes.
如果是空的,那么我们将显示任何客户的错误状态代码。否则,我们将首先检查该错误代码是否属于给定的List状态代码的一部分。
3. Using the Custom Configurer
3.使用自定义配置器
Now that we have our custom API, we can add it to the Spring Security configuration by defining the bean, then by using the apply() method of HttpSecurity:
现在我们有了自定义的API,我们可以通过定义Bean,然后通过使用HttpSecurity的apply()方法将其添加到Spring安全配置中。
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
//...
.and()
.apply(clientErrorLogging());
return http.build();
}
@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
return new ClientErrorLoggingConfigurer();
}
}
We can also define the bean with a specific list of error codes we want to log:
我们也可以用我们想要记录的错误代码的具体列表来定义这个bean。
@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
return new ClientErrorLoggingConfigurer(Arrays.asList(HttpStatus.NOT_FOUND)) ;
}
And that’s all! Now our Security Configuration will include the custom filter and display the log messages.
这就是全部!现在我们的安全配置将包括自定义过滤器并显示日志信息。
If we want the custom configurer to be added in by default, we can use the META-INF/spring.factories file:
如果我们想让自定义配置器默认加入,我们可以使用META-INF/spring.plants文件。
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.baeldung.dsl.ClientErrorLoggingConfigurer
And to disable it manually, we can then use the disable() method:
而要手动禁用它,我们就可以使用disable()方法。
//...
.apply(clientErrorLogging()).disable();
4. Conclusion
4.结论
In this quick tutorial, we focused on an advanced feature of the Spring Security configuration support – we’ve seen how to define our own, custom SecurityConfigurer.
在这个快速教程中,我们重点介绍了Spring安全配置支持的一个高级功能–我们已经看到了如何定义我们自己的、自定义的SecurityConfigurer。
As always, the full source code of the example can be found over on GitHub.
一如既往,该示例的完整源代码可以在GitHub上找到over。