知識庫 / Spring / Spring Security RSS 訂閱

自定義 Spring Security 配置

Spring Security
HongKong
4
02:06 PM · Dec 06 ,2025

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

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

發佈 評論

Some HTML is okay.