Filter, FilterChain

귀찮Lee·2022년 7월 25일
1

Spring Security

목록 보기
2/13

◎ Filter (Servlet Filter)

  • Filter

    • 클라이언트가 서버로 요청을 하게되면 가장 먼저 Servlet Filter를 거치게 된다.

    • 필터는 클라이언트와 어떤 URL에 해당하는 자원 사이에서 요청과 응답 정보를 이용해 다양한 처리를 함

      • ex1) 다른 자원으로 리다이렉트
      • ex2) 다음 필터로 진행없이 응답 처리
      • ex3) 다음 필터 및 서블릿 처리
    • Filter를 모두 거치고난 후 DispatcherServlet과 같은 Servlet에서 요청이 처리

    • Spring Security는 주요 보안에 대한 처리를 여러가지의 Filter로 처리하도록 구성

      • 인증(Authentication), 인가(Authorization) 등의 처리를 수행
      • 자동 설정 옵션을 사용하면, 10개의 스프링 시큐리티 필터가 자동으로 설정

◎ Filter Chain

  • Filter Chain

    • 단일 HTTP 요청을 처리하는 전형적인 레이어, 여러개의 Filter들이 사슬처럼 연결되어 있고 서로 연결되어 연쇄적으로 동작함
    • Filter는 요청이 DispatcherServlet에 의해 다뤄지기 전,후에 동작
  • Filter Chain 특징

    • 체인을 형성하여 순서를 지정하며 실제로 요청 자체를 처리하려는 경우 필터가 나머지 체인을 거부 할 수 있다.
    • 다운스트림 필터와 서블릿을 사용해서 요청과 응답을 수정할 수도 있다.
    • Filter는 FilterChain 안에 있을 때 효력을 발휘
  • Filter Chain 순서 관리

    • Filter 타입의 @Beans에 @Order를 붙이거나 Orderd를 구현
    • API의 일부로 순서를 가지는 FilterRegistrationBean의 일부가 되는 것
  • 기타

    • 클라이언트는 애플리케이션으로 요청을 전송하고, 컨테이너는 Servlet과 여러 Filter로 구성된 FilterChain을 만들어 요청 URI path 기반으로 HttpServletRequest를 처리

    • 1개의 Servlet이 HttpServletRequest와 HttpServletResponse 처리를 담당

      • Filter는 여러 개를 사용 가능
      • 다운스트림의 Servlet과 Filter의 실행을 막는 경우, Filter에서 HttpServletResponse를 작성
      • 다운스트림에 있는 Servlet과 여러 Filter로 HttpServletRequest나 HttpServletResponse를 수정 가능함

◎ Filter 인터페이스

  • Filter method

    • init(FilterConfig filterConfig) : 핕러를 웹 컨테이너 내에 생성한 후 초기화할 때 호출한다.
    • doFilter(ServletRequest, ServletResponse, FilterChain) : 체인을 따라 다음에 존재하는 필터로 이동
    • destroy() : 필터가 웹 컨테이너에서 삭제될 때 호출함
  • 구현 예시

    public class FirstFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
            System.out.println("FirstFilter 생성됨");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("First 필터 시작");
            chain.doFilter(request, response);
            System.out.println("First 필터 종료");
        }
    
        @Override
        public void destroy() {
            System.out.println("FirstFilter 사라짐");
            Filter.super.destroy();
        }
    }
    @Configuration
    public class Config {
    
        @Bean
        public FilterRegistrationBean<FirstFilter> firstFilterRegister()  {
            FilterRegistrationBean<FirstFilter> registrationBean = new FilterRegistrationBean<>(new FirstFilter());
            registrationBean.setOrder(1);
            return registrationBean;
        }
    
        @Bean
        public FilterRegistrationBean<SecondFilter> secondFilterRegister()  {
            FilterRegistrationBean<SecondFilter> registrationBean = new FilterRegistrationBean<>(new SecondFilter());
            registrationBean.setOrder(2);
            return registrationBean;
        }
    
    }
    First 필터 시작
    Second 필터 시작
    
    Second 필터 종료
    First 필터 종료

◎ DelegatingFilterProxy

  • DelegatingFilterProxy

    • 서블릿 필터(Filtern)에서 서블릿 필터를 구현한 스프링 빈에게 요청을 위임해주는 대리자 역할의 서블릿 필터
  • DelegatingFilterProxy 필요성

    • Servlet Filter는 스프링에서 정의 된 Bean을 주입해서 사용할 수 없음.

      • Spring Bean: 스프링 컨테이너에서 생성및 관리하는 컴포넌트
      • ServletFilter: 서블릿 컨테이너에서 생성및 관리하는 필터
      • 서로 실행되는 위치가 다르기 때문에 Bean을 Servlet Filter에 주입할 수 없다.
    • 특정한 이름을 가진 스프링 빈을 찾아 그 빈에게 요청을 위임

      • 서블릿 필터는 DelegatingFilterProxy 클래스를 사용해서 스프링 빈에게 요청을 위임하면 스프링 빈에서 구현한 서블릿 필터를 이용해 책임을 수행
      • springSecurityFilterChain 이름으로 생성된 빈을 ApplicationContext 에서 찾아 요청을 위임
  • 내부 구조
    • DelegatingFilterProxy라는 Filter 구현체로 서블릿 컨테이너의 생명주기와 스프링 ApplicationContext(스프링 컨테이너)를 연결
    • DelegatingFilterProxy는 표준 서블릿 컨테이너 메커니즘으로 등록할 수 있으면서도 모든 처리를 Filter를 구현한 스프링 빈으로 위임한다.

◎ FilterChainProxy

  • FilterChainProxy

    • 각 필터들을 순서대로 호출하며 인증/인가처리 및 각종 요청에 대한 처리를 수행
    • DelegatingFilterProxy로 부터 요청을 위임 받고 실제 보안 처리
    • 스프링 시큐리티 초기화 시 생성되는 필터들을 관리하고 제어
      • 스프링 시큐리티가 기본적으로 생성하는 필터
      • 설정 클래스에서 API추가 시 생성되는 필터
  • 실행 과정

    • DelegatingFilterProxy가 요청을 받게 될 경우 자신이 요청받은 요청객체를 delegate request로 요청 위임
    • 요청 객체는 특정한 필터(springSecurityFilterChain) 에서 받게 된다.
      • springSecurityFilterChain 동일한 이름으로 등록하여 내부적으로 해당 이름을 가진 객체를 찾는 것
      • springSecurityFilterChain 필터를 가지고 있는 빈(Bean) FilterChainProxy이다.
    • FilterChainProxy에서는 자신이 가진 각각의 필터들을 차례대로 수행하며 보안처리를 수행
    • 보안처리가 완료되면 최종 자원에 요청을 전달하여 다음 로직이 수행

◎ 참고 자료

profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

0개의 댓글