1. 概述
Spring Security Java 配置支持提供強大的流暢 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,然後使用apply()方法來將其添加到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)) ;
}
而且就這麼多了!現在我們的Security配置將包含自定義過濾器並顯示日誌消息。
如果我們想默認添加自定義配置器,則可以使用META-INF/spring.factories文件:
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.baeldung.dsl.ClientErrorLoggingConfigurer
要手動禁用它,則可以使用disable()方法:
//...
.apply(clientErrorLogging()).disable();
4. 結論
在本快速教程中,我們重點介紹了 Spring Security 配置支持的高級功能——我們已經學習瞭如何定義我們自己的自定義 SecurityConfigurer