Security Filter 는 @Bean 으로 등록하지 말자
안녕하세요. 프로젝트에 스프링 시큐리티를 적용하며 겪었던 문제 상황을 공유합니다.
등록하지 않은 필터가 동작하는 현상
스프링 시큐리티의 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
를 빈으로 등록했기 때문입니다. 스프링 공식문서에 따르면 필터 클래스를 스프링 빈으로 등록시키면 필터로 동작한다고 되어있습니다.
디버깅으로 내부를 들여다봤을 때, 스프링 시큐리티의 FilterChain
에는 등록되지 않았지만, ApplicationFilterChain
의 필터로 TestFilter
가 등록된 것을 확인할 수 있었습니다. 오직 스프링 시큐리티의 필터만으로 동작하길 원한다면 필터를 빈으로 등록하면 안된다는 결론을 얻었습니다.
참고로 DelegatingFilterProxyRegistrationBean
은 스프링 시큐리티의 FilterChain
이 동작할 수 있도록 해주는 필터인데 TestFilter
이전에 등록되어 있는 것을 확인할 수 있습니다. TestFilter
의 순서를 @Order(0)
애노테이션으로 조작해봤지만 TestFilter
의 순서는 그림과 같은 결과였습니다. DelegatingFilterProxyRegistrationBean
까지의 순서는 고정이고, 그 이후의 순서는 @Order
애노테이션에 의해 결정되는 사실을 알 수 있었습니다.
결론
스프링 시큐리티의 필터체인에 적용할 필터는 Bean 으로 등록하지 말자.