1. 概述
Spring Security Java 配置支持提供強大的 Fluent API – 用於定義應用程序的安全映射和規則。
在本文快速介紹中,我們將看到如何進一步擴展,實際定義自定義配置器;這是一種高級且靈活的方式,可以將自定義邏輯引入標準安全配置。
對於我們的快速示例,我們將添加功能,根據給定的錯誤狀態碼,為已認證的用户記錄錯誤。
2. 自定義 SecurityConfigurer
為了開始定義我們的配置器,首先 我們需要擴展 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);
}
}在這裏,我們需要重寫的主方法是configure()方法——它包含該配置器將應用的安全性配置。
在我們的示例中,我們在 Spring Security 過濾器之後註冊了一個新的過濾器。 此外,由於我們打算記錄響應狀態錯誤代碼,我們添加了errorCodes List屬性,以便我們可以控制我們將記錄的錯誤代碼。
我們還可以選擇在 init()方法中添加額外的配置,該方法在 configure()方法之前執行。
接下來,讓我們定義我們在自定義實現中註冊的 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);
}
}這是一個標準的 Spring 過濾器類,它繼承了 GenericFilterBean並覆蓋了 doFilter()方法。它有兩個屬性,分別代表用於顯示消息的日誌記錄器以及 List類型的 errorCodes。
讓我們更詳細地瞭解一下 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);
}
}如果狀態碼是客户端錯誤狀態碼,即介於 400 到 500 之間,則我們會檢查 errorCodes 列表。
如果該列表為空,則我們會顯示任何客户端錯誤狀態碼。否則,我們會首先檢查該狀態碼是否包含給定的 List 狀態碼列表。
3. 使用自定義配置器
現在我們已經擁有自定義 API,可以通過定義 Bean 並使用 <em apply()</em> 方法來將其添加到 Spring Security 配置中。
@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();
}
}我們還可以定義一個包含特定錯誤代碼列表的 Bean,以便進行日誌記錄:
@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
return new ClientErrorLoggingConfigurer(Arrays.asList(HttpStatus.NOT_FOUND)) ;
}這就是全部!現在我們的安全配置將包含自定義過濾器並顯示日誌消息。
如果我們希望自定義配置項默認添加,可以使用 META-INF/spring.factories 文件:
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.baeldung.dsl.ClientErrorLoggingConfigurer要手動禁用它,我們可以使用 disable() 方法:
//...
.apply(clientErrorLogging()).disable();4. 結論
在本快速教程中,我們重點介紹了 Spring Security 配置支持中的一個高級特性——我們已經學習瞭如何定義自己的自定義 SecurityConfigurer 。