自定義 Spring Security 配置

Spring Security
Remote
1
02:54 AM · Nov 30 ,2025

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() 方法。 它具有兩個表示我們將用於顯示消息的日誌記錄器和 ListerrorCodes 屬性。

讓我們更詳細地瞭解 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

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.