[ASAC 3기 개발일지] Spring Security - Filter와 Interceptor

배규리·2023년 11월 15일
1
post-thumbnail

Spring을 활용하여 개발한 웹 애플리케이션들은 일부 혹은 모든 사용자에게 서비스를 제공하기 때문에 보안이 매우매우 중요하다!!⭐
이를 위해 Spring Security라는 것이 존재한다.

  • Spring Security: Spring 기본적으로 로그인, 세션에 관련된 모듈 및 설정 손쉽게 사용 가능하도록 제공
  • Filter Chain: 웬만한 모듈들은 Spring Security가 제공하기에 거의 다 활용 가능 or 커스텀도 가능
    • 요청 URL에 따라 다른 처리 가능
    • 모든 요청에 따로 개발한 인증 모듈을 적용 가능

그렇다면 이제 Filter와 Interceprot에 대해서 알아보자!
알아보기에 앞서 보안이랑 이 두 친구가 무슨 관련이 있느냐

Spring Security에서 모든 보안 처리는 Filter의 집합(SecurityFilterChain)을 통해 동작된다.

먼저 둘의 공통점은 Spring Controller에 요청이 전달되기 전에 Middleware처럼 URI별 중앙 처리가 필요한 경우에 사용한다는 점!

가장 큰 차이점은 Spring MVC Architecture의 Front Controller 패턴을 기점으로 나뉜다는 점이다!🛣️

Filter(Servlet)

Filter는 Tomcat(WAS)의 Deployment Descriptor 내 설정
Spring Controller에 요청이 도달하기 이전에 중간 작업을 위해 사용한다.

구체적인 사용 목적은 아래와 같다.

  • 요청 및 응답 데이터 변환/유효성 검사
  • 권한 부여 및 인증
  • 로깅 및 모니터링

Filter는 Spring Bean으로 등록이 가능하며, 내부에서 Spring Bean 활용도 가능하다.

그렇다면 먼저 Filter 인터페이스를 살펴보자!
구현하여 사용할 수 있는 메서드가 아래와 같이 3개 존재한다.

public interface Filter {

    public default void init(FilterConfig filterConfig) throws ServletException {}
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
    public default void destroy() {}
    
}

init()

필터 초기화 메소드
Servlet Container가 해당 필터 생성시 호출

destroy()

필터 종료 메소드
Servlet Container가 해당 필터 종료시 호출

doFilter()

클라이언트 요청이 올 때마다 호출, Request/Response시 나누어 처리 가능
이 메소드는 조금 중요한 게 init이나 destroy와 달리 한번만 호출되는 것이 아니라 클라이언트 요청 발생할 때마다! 호출된다는 점 기억하기! ⭐⭐⭐

Filter는 하나의 함수가 요청 진입 시&결과 반환 시, 모두 커버 가능하여 전역 처리 로직에 적합하다.

Interceptor(Spring)

Spring Controller에 요청이 도달하기 이전에 중간 작업을 위해 사용한다.

구체적인 사용 목적은 아래와 같다.

  • 데이터 변환 및 처리
  • 권한 검사, 로깅, 트랜잭션 관리 등과 같은 요청 전/후 처리
  • 권한 부여 및 권한 체크

Interceptor 인터페이스도 살펴보자!
구현하여 사용할 수 있는 메서드가 아래와 같이 3개 존재한다.

public interface HandlerInterceptor {

	default boolean **preHandle**(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; }
	default void **postHandle**(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}
	default void **afterCompletion**(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}

preHandle()

요청이 Controller에 진입하기 직전에 호출
false 반환 시 Controller에 미진입

postHandle()

결과를 Controller가 반환하는 직후에 호출

afterCompletion()

Controller 결과에 따른 View 생성 혹은 에러 발생과 상관없이 호출

Filter와 Interceptor의 차이점

두 가지의 큰 차이점을 3가지로 나타낼 수 있다.
관리주체 차이, 호출시기 차이, 커버리지 차이 이렇게 3가지다.

관리 주체

Filter: Tomcat에서 관리 (Servlet Container)
Interceptor: Spring에서 관리 (Spring Container)

호출 시기

Filter: Front Controller 앞단(DispatcherServlet 앞쪽)

  • doFilter()
    • 요청이 DispatcherServlet.service()에 진입하기 직전(init() 후)에 호출
    • 결과를 DispatcherServlet.service()가 반환하는 직후(destroy() 전)에 호출

Interceptor: Front Controller 뒷단(Controller 앞쪽)

  • preHandle(): 요청이 Controller에 진입하기 직전에 호출
  • postHandle(): 결과를 Controller가 반환하는 직후에 호출
  • afterCompletion(): Controller 성공/실패 결과에 따라 View를 생성한 직후에 호출

커버리지

Filter: Tomcat은 WAS이니 정적 리소스 반환 등의 WS 처리도 수행, Filter는 여기까지 적용
Interceptor: Spring Controller(Handler)요청, 반환에 대해서만 Interceptor 적용

그렇다면 Filter만 사용하면되지 왜 Interceptor까지 사용할까?
Filter는 Servlet Container에서 동작하여 모든 요청에 대해 실행되므로 보다 저수준의 작업을 처리하기에 적합하다.
반면에 Interceptor는 주로 프레임워크나 비즈니스 로직에 특화된 작업을 처리할 때 사용되며, 스프링과 같은 프레임워크에서 제공하는 레벨에서 사용된다.

profile
백엔드 개발은 취미인 AI 개발자🥹

1개의 댓글

comment-user-thumbnail
2024년 4월 19일

혹시 여쭤보고싶은게있는데 카톡이나 메일주소 알려주실수있을까요?

답글 달기