커스텀 필터를 만들었을 때, @Componenet
어노테이션을 통해 해당 필터를 bean으로 등록했는지의 여부에 따라 filter가 web ignoring에 의해 무시되지 않는 상황이 발생했다.
첫번째는 @component
로 빈을 등록했을 때이고, 두번째는 빈으로 등록하지 않았을 때이다.
왜 이런 상황이 발생했는지 차근차근 알아보자.
🌱 Spring Security
Spring 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크
먼저 Spring Security의 구조를 먼저 이해할 필요가 있다.
클라이언트 요청은 서버 컴퓨터의 WAS(톰캣)의 필터들을 통과한 뒤 스프링 컨테이너의 컨트롤러에 도달한다.
WAS의 필터단에서 요청을 가로챈 후 시큐리티의 역할을 수행한다.
즉 정리하면 전체적인 동작 과정은 위와 같다. 왼쪽의 FilterChain은 WAS의 필터체인이고 오른쪽의 SecurityFilterChain은 Spring Security에서 사용하는 필터체인이다. 즉, HTTP요청을 가져와야하기 때문에 WAS의 필터단에 위치하는 특별한 필터인 Delegating Filter Proxy에서 요청을 가로채서 SecurityFilterChain으로 연결시켜준다.
여기서 주목해야할 점은 우리가 @Component
어노테이션을 사용해서 빈으로 등록된 filter는 SecurityFilterChain에 위치하는 것이 아니라 WAS의 필터단에 위치한다는 것이다.
@RequiredArgsConstructor
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter { ... }
즉, 위와 같이 @Component
어노테이션과 Filter 인터페이스를 이용하면 필터체인에 추가되는데, 이 경우 WAS의 ApplicationFilterChain에 추가되는 것이다.
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers(whiteList);
}
WebSecurity.ignoring() 은 필터가 없는 SecurityFilterChain 을 만들게 되고,whiteList에 포함된 경로에 대한 요청을 필터가 존재하지 않는 SecurityFilterChain으로 전달한다
@Component
로 등록한 MyCustomFilter(JwtAuthenticationFilter)는 WAS의 ApplicationFilterChain에 등록되어 있기 때문에 ignoring을 해주어도 항상 해당 커스텀 필터를 지나게 된다.