[Spring Security] Spring Security 필터 순서 변경하기

2022. 1. 24. 02:18Spring/Security

최근 상경을 위해 알바를 시작해서 출퇴근시간까지 합해서 주5일 하루에 10시간씩 일하게 되어 공부나 포스팅하기가 힘들다.. ㅜㅜ 그래도 조금씩이나마 포스팅을 진행하고자 한다.

토이 프로젝트를 진행하던 중 커스텀 필터를 만들게 되었다. 그런데 분명 setOrder(1)로 지정했음에서 스프링 시큐리티에서 생성된 필터가 항상 앞서 적용되는 것을 확인했다.

이는 스프링 시큐리티에서 설정된 setOrder의 기본값이 -100으로 설정되어 있어서 생긴 현상이었다.

application.yml(또는 properties)에서 이를 변경해주면 해결된다.

그런데 나머지 필터들은 스프링 부트에서 자동으로 등록한 필터같은데 그 역할이 궁금해져서 검색해보았다.

OrderedCharacterEncodingFilter

스프링에서 웹 요청과 응답 시 인코딩 관련 처리를 하기 위해 등록한 필터이다. 순서는 Integer.MIN_VALUE, 즉 -2147483648이다. 따라서 가장 먼저 적용되는 필터이다.

OrderedFormContentFilter

서블릿은 기본적으로 요청 메서드 중 POST만 지원한다. 스프링에서는 그 외에 PUT, PATCH, DELETE를 지원하기 위해 FormContentFilter를 만들어 등록한다. 그리고 이를 상속한 필터가 OrderedFormContentFilter이다. 그리고 코드를 직접 보면 아래와 같이 반드시 스프링 시큐리티 필터보다 먼저 적용되도록 되어 있다.

OrderedRequestContextFilter

서블릿은 모든 요청에 대해 Thread-safe를 보장한다. 따라서 각 요청마다 다른 컨텍스트를 가지는데 각 컨텍스트를 LocaleContextHolder와 RequestContextHolder에 넣고 지우는 역할을 하는 게 이 필터이다. 위와 같이 핵심은 RequestContextFilter이다. 공식 문서의 설명을 보면 다음과 같다(다음 생엔 영어권에서 태어났으면..).

LocaleContextHolder와 RequestContextHolder를 통해 현재 쓰레드의 요청을 드러내기 위한 서블릿 필터이다. 스프링의 RequestContextListener와 DispatcherServlet 또한 현재 쓰레드에 대한 같은 요청 컨텍스트를 드러낸다. 이 필터는 주로 JSF의 FacesServlet같은 서드파티 서블릿에 사용된다. 스프링 자체의 웹 지원 안에서 DispatcherServlet의 처리는 완벽하게 충분하다.

구현 코드를 보면 다음과 같다.

해당 필터가 시작될 때 LocaleContextHolder와 RequestContextHolder를 초기화하고 doFilter를 수행한 후 두 Holder의 컨텍스트를 리셋한다. 따라서 필터를 직접 만들어서 등록할 경우 이 필터 이후에 적용하는 것이 바람직하게 보인다.
이 필터의 순서는 -105이다. 위 필터들 중 가장 마지막에 적용된다.

정리

필터 이름 역할 Order Number 순서
OrderedCharacterEncodingFilter 인코딩 처리 -2147483648 1
OrderedFormContentFilter 요청 메서드 처리 -9900 2
OrderedRequestContextFilter 요청 별 컨텍스트 처리 -105 3