본문 바로가기
Java/Spring

[Spring Security] Servlet Filter 등록과 동작 순서 (1)

by 오늘의개발부 2022. 1. 12.
반응형

  Spring Security + JWT 스터디를 하다가 시작된 의문으로 파보게 된 Filter...

  첫번째는 Security와는 약간 다른 얘기지만 Servlet Filter의 등록과 동작순서부터 알아봤다.

 

 

 

간단하게 Filter interface를 구현하여 Custom filter를 세개 만들었다.

아래와같이 ATestFilter, BTestFilter, DTestFilter를 만들고 @Component 어노테이션으로 간단하게 등록했다.

 

@Component
public class ATestFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("----------------------------ATEST Request------------------------------------");
		chain.doFilter(request, response);
		System.out.println("----------------------------ATEST Response------------------------------------");
	}
	
}

 

 

 

그리고 요청을 보내면

 

...
----------------------------ATEST Request------------------------------------
----------------------------BTEST Request------------------------------------
----------------------------DTEST Request------------------------------------
...(동작)
----------------------------DTEST Response------------------------------------
----------------------------BTEST Response------------------------------------
----------------------------ATEST Response------------------------------------

 

 

순서를 정해주지 않으면 Default로 등록된 컴포넌트의 알파벳 순서에 따라 작동한다.

 

 

 

 

이 상태에서 순서를 지정하려면 @Order 어노테이션을 이용을 이용해 컴포넌트의 로드 순서를 정한다.

A, B, D Filter의 순서를 거꾸로 3, 2, 1로 지정해줬다.

 

@Component
@Order(3)
public class ATestFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("----------------------------ATEST Request------------------------------------");
		chain.doFilter(request, response);
		System.out.println("----------------------------ATEST Response------------------------------------");
	}
	
}

 

 

 

다시 요청을 보내면 순서를 지정한대로 표출된다.

 

...
----------------------------DTEST Request------------------------------------
----------------------------BTEST Request------------------------------------
----------------------------ATEST Request------------------------------------
...(동작)
----------------------------ATEST Response------------------------------------
----------------------------BTEST Response------------------------------------
----------------------------DTEST Response------------------------------------

 

 

 

 

  이 외에 특정 URL 패턴에만 특정 Filter를 적용하고 싶다면 @WebFilter(urlPatterns= "/user/*") 와 같이 @WebFilter 어노테이션을 이용하는 방법이 있다.

  다만 주의해야할 점은 @WebFilter 어노테이션이 붙은 필터를 컴포넌트로 등록하고 싶다면 @ServletComponentScan 어노테이션을 메인 어플리케이션 클래스에 붙여줘야 하며, 만약 Filter 클래스에 @WebFilter와 @Component 어노테이션 두개가 동시에 붙어있다면 @ServletComponentScan, @ComponentScan이 각각 동작할 때 해당 Filter를 두번 등록하여 실행도 두번 될 수 있으니 @WebFilter 사용시 @Component는 지워줘야한다.

 

  Filter 클래스의 직접 수정이 불가능한 경우 @Configuration 을 사용하는 클래스를 만들어 FilterRegistrationBean을 등록하면서 Filter를 FilterRegistrationBean에 추가하면서 URL 패턴이나 order를 지정해줄 수 있다.

 

 

 

 

 

 그러면 Spring Security를 사용하는 프로젝트에서 위와 같은 Servlet 필터와 Spring Security Filter의 동작 순서는 어떻게 될까?

 

 

현재 내 프로젝트의 Security Ffilter chain은 아래와 같다. 그리고 Servlet 필터는 위에 등록한 A, B, C TestFilter가 있다.

JwtAuthenticationFilter에만 로그를 찍어봤다.

 

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  CorsFilter
  LogoutFilter
  JwtAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

 

 

 

출력된 로그 는 아래와 같다. Spring Security Filter chain이 먼저 동작한 후 Servlet Filter가 동작했다.

 

-----------------------JwtAuthenticationFilter Request-----------------------
----------------------------DTEST Request------------------------------------
----------------------------BTEST Request------------------------------------
----------------------------ATEST Request------------------------------------
...(동작)
----------------------------ATEST Response------------------------------------
----------------------------BTEST Response------------------------------------
----------------------------DTEST Response------------------------------------
-----------------------JwtAuthenticationFilter Response-----------------------

 

 

 

만약 Custom filter가 Spring Security Filter 보다 먼저 동작하게 하려면 application.yml에 다음과 같이 추가할 수 있다.

 

spring.security.filter.order=10

 

이렇게 하면 Spring Security Filter 앞에 10개의 Filter를 넣을 수 있는 공간이 생긴 셈이다.  

 

 

 

다음 포스트에서는 이제 본격적으로 Spring Security filter chain을 파헤쳐봐야겠다.

반응형