ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot "You are asking Spring Security to ignore Ant [pattern]" 경고 해결(WebSecurity ignoring -> HttpSecurity permitAll)
    spring 2023. 2. 1. 16:21
    반응형

    Spring Security 의 구조에 대해서 알면 도움이 된다.

    참고:

    - Spring Security 공식 문서: https://docs.spring.io/spring-security/reference/servlet/architecture.html

    - HttpSecurity, WebSecurity 를 통한 SecurityFilterChain 설정: https://bitgadak.tistory.com/10


    Spring 버전

    Spring Security 의 경우 Deprecated 된 부분이 있기 때문에 나중에 변경될 수 있다. 이번에 사용한 버전은 아래와 같다.

    • Spring Boot: 2.7.8
    • Spring Security: 5.7.6

    경고가 발생하는 경우

    Spring Boot 에서는 SecurityFilterChain, WebSecurityCustomizer 를 Bean으로 설정함으로 Security 설정을 할 수 있다. (이전에는 WebSecurityConfigurerAdapter 를 상속하여 설정하는 방식이었는데, deprecated 되었다.) 예를 들어 아래와 같이 설정할 수 있다.

    @Configuration
    public class SecurityConfig {
    
      @Bean
      public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .anyRequest().authenticated();  // 모든 요청에 대해 권한 처리
        http.formLogin();  // 로그인페이지
        return http.build();
      }
    
      @Bean
      public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/static/**");  // "/static/**" 으로 들어오는 요청 무시
      }
    }

     

    이 때, WebSecurityCustomizer 에서 WebSecurity의 ignoring 을 사용하면 경고 메시지가 뜬다.

    You are asking Spring Security to ignore Ant [pattern='/static/**']. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.

    메시지가 발생하는 이유

    찾아보면 메시지가 출력되는 이유를 설명하고 있는 곳을 발견할 수 있다.

    https://github.com/spring-projects/spring-security/issues/10938

     

    WARN when ignoring antMatchers - please use permitAll · Issue #10938 · spring-projects/spring-security

    When I use web.ignoring().antMatchers() I'd like to see a DEBUG message instead of a WARNING for each ignored pattern. I'm confused by the message saying it's not recommended and I shou...

    github.com

    이곳에 따르면 WebSecurity.ignoring() 을 사용할 경우 Spring Security의 어떠한 보호도 받을 수 없기 때문에 permitAll 를 사용하라고 권장하고 있다. 또한 ignoring() 을 사용할 때만 얻을 수 있는 성능상의 이점도 없다고 하며 성능을 고려한 설정 방법 또한 제시하고 있다.


    수정

    위 사이트를 참고하여 처음의 설정파일을 바꾸면 아래와 같다.

    @Configuration
    public class SecurityConfig {
    
      @Bean
      @Order(2)
      public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .anyRequest().authenticated();  // 모든 요청에 대해 권한 처리
        http.formLogin();  // 로그인페이지
        return http.build();
      }
    
      @Bean
      @Order(1)
      public SecurityFilterChain exceptionSecurityFilterChain(HttpSecurity http) throws Exception {
        http
                .requestMatchers((matchers) -> matchers.antMatchers("/static/**"))
                .authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
                .requestCache().disable()
                .securityContext().disable()
                .sessionManagement().disable();
    
        return http.build();
      }
    }

    exceptionSecurityFilterChain 메서드를 통해 새로 생성한 SecurityFilterChain은 기존에 있는 SecurityFilterChain 보다 먼저 경로 체크를 해야 하기 때문에 순서를 정할 필요가 있다. @Order 어노테이션을 통해 /static/** 경로로 오는 요청에 대해 먼저 체크하도록 한다.

    사이트에서 언급한 대로 requestCache, securityContext, sessionManagement 에 대한 필터를 제거하도록 한다.


    검사

    새로 만든 SecurityFilterChain 의 경우 어떤 필터가 있는지 기존 필터체인과 비교해 본다.

    디버거를 이용하여 확인해 보면 기존의 필터체인은 15개의 필터를 가지고 있음을 알 수 있다.

    filters = {ArrayList@7327}  size = 15
     0 = {DisableEncodeUrlFilter@7339} 
     1 = {WebAsyncManagerIntegrationFilter@7340} 
     2 = {SecurityContextPersistenceFilter@7341} 
     3 = {HeaderWriterFilter@7342} 
     4 = {CsrfFilter@7343} 
     5 = {LogoutFilter@7344} 
     6 = {UsernamePasswordAuthenticationFilter@7345} 
     7 = {DefaultLoginPageGeneratingFilter@7346} 
     8 = {DefaultLogoutPageGeneratingFilter@7347} 
     9 = {RequestCacheAwareFilter@7348} 
     10 = {SecurityContextHolderAwareRequestFilter@7349} 
     11 = {AnonymousAuthenticationFilter@7350} 
     12 = {SessionManagementFilter@7351} 
     13 = {ExceptionTranslationFilter@7352} 
     14 = {AuthorizationFilter@7353}

    새로 생성한 필터체인의 경우는 8개의 필터를 가지고 있다.

    filters = {ArrayList@7324}  size = 8
     0 = {WebAsyncManagerIntegrationFilter@7330} 
     1 = {HeaderWriterFilter@7331} 
     2 = {CsrfFilter@7332} 
     3 = {LogoutFilter@7333} 
     4 = {SecurityContextHolderAwareRequestFilter@7334} 
     5 = {AnonymousAuthenticationFilter@7335} 
     6 = {ExceptionTranslationFilter@7336} 
     7 = {AuthorizationFilter@7337}

    성능에 영향을 줄 수 있는 세션, 캐시, 컨텍스트와 관련된 필터가 사라진 것을 확인할 수 있다.

     

    참고) authorizeRequests 가 아닌 authorizeHttpRequests 를 사용하였기 때문에 맨 마지막에 FilterSecurityInterceptor가 아닌 AuthrizationFilter가 있음을 알 수 있다.

    반응형

    댓글

Designed by Tistory.