티스토리 뷰

안녕하세요. 프로젝트에 스프링 시큐리티를 적용하며 겪었던 문제 상황을 공유합니다.

 

등록하지 않은 필터가 동작하는 현상

스프링 시큐리티의 FilterChain Bean 을 조작하여 커스텀 필터를 추가할 수 있습니다. 로그인 필터를 구현한 후, API를 테스트할 때마다 로그인하는 것이 귀찮았습니다. 잠시 로그인 필터를 빼놓으려고 주석처리를 했음에도 여전히 필터가 동작하는 이상한 현상이 일어났습니다.

public class TestFilter extends AbstractAuthenticationProcessingFilter {
    public TestFilter(String defaultUrl) {
        super(defaultUrl);
    }
}
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager manager){
        // 필터 등록을 주석처리!
        // http.addFilterBefore(testFilter(manager), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public TestFilter testFilter(AuthenticationManager authenticationManager) {
        TestFilter filter = new TestFilter("/login");
        return filter;
    }
}

TestFilter 클래스는 스프링 시큐리티의 FilterChain에 추가할 필터입니다. SecurityConfig 클래스는 스프링 시큐리티를 설정하기 위한 클래스입니다. 필터 등록을 주석 처리한 것을 확인 할 수 있습니다. 따라서 필터가 동작하지 않는 결과를 기대할 수 있습니다. 하지만 실행시켜보면 필터는 동작합니다.

 

원인 

testFilter를 빈으로 등록했기 때문입니다. 스프링 공식문서에 따르면 필터 클래스를 스프링 빈으로 등록시키면 필터로 동작한다고 되어있습니다.

ApplicationFilterChain 을 디버깅한 그림

디버깅으로 내부를 들여다봤을 때, 스프링 시큐리티의 FilterChain에는 등록되지 않았지만, ApplicationFilterChain 의 필터로 TestFilter가 등록된 것을 확인할 수 있었습니다. 오직 스프링 시큐리티의 필터만으로 동작하길 원한다면 필터를 빈으로 등록하면 안된다는 결론을 얻었습니다.

 

참고로 DelegatingFilterProxyRegistrationBean은 스프링 시큐리티의 FilterChain이 동작할 수 있도록 해주는 필터인데 TestFilter 이전에 등록되어 있는 것을 확인할 수 있습니다. TestFilter의 순서를 @Order(0) 애노테이션으로 조작해봤지만 TestFilter의 순서는 그림과 같은 결과였습니다. DelegatingFilterProxyRegistrationBean 까지의 순서는 고정이고, 그 이후의 순서는 @Order 애노테이션에 의해 결정되는 사실을 알 수 있었습니다.

 

결론

 스프링 시큐리티의 필터체인에 적용할 필터는 Bean 으로 등록하지 말자.

댓글