Java/Spring Security

Servlet Filter 구현

마손리 2023. 5. 13. 13:01

Filter 구현

public class FirstFilter implements Filter {
    // (1) 초기화 작업
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("First Filter 생성");
    }

    // (2)
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException {
        // (2-1) request(ServletRequest)를 이용해 다음 Filter로 넘어가기 전, 전처리 작업을 수행
        System.out.println("----------------First Filter 시작 ----------------");
        
        // (2-2) 현재 FilterChain의 다음 Filter 호출
        chain.doFilter(request, response);

        // (2-3) response(ServletResponse)를 이용해 response에 대한 후처리 작업을 수행
        System.out.println("----------------First Filter 종료 ----------------");
    }

    // (3)
    public void destroy() {
        // (4) Filter가 사용한 자원을 반납하는 처리
        System.out.println("FirstFilter Destroy");
        Filter.super.destroy();
    }
}

위의 코드와 같이 Filter 인터페이스를 구현해주는 것만으로 Servlet filter를 정의해줄 수 있다.

 

init(), doFilter(), destroy() 메서드는 각각 filter의 초기화작업, filter의 실질적인 로직, filter의 자원반납의 기능을 수행하며 doFilter() 메서드에서는 현재의 FilterChain의 다음 Filter를 호출한다.

 

 

구현된 Filter를 적용하기 위한 FilterConfiguration 구성

@Configuration
public class FilterConfiguration {
    @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;
    }
    @Bean
    public FilterRegistrationBean<ThirdFilter> ThirdFilterRegister()  {
        FilterRegistrationBean<ThirdFilter> registrationBean = new FilterRegistrationBean<>(new ThirdFilter());
        registrationBean.setOrder(3); 
        return registrationBean;
    }
}

(Filter 3개를 구현하여 적용시킨 코드)

 

@Configuration과  @Bean을 사용하여 Spring container으로써 FilterRegistrationBean의 생성자로 Filter 인터페이스의 구현 객체를 넘겨주는 형태로 등록할 수있다.

 

FilterRegistrationBeansetOrder() 메서드를 이용하여 해당 필터 체인의 순서를 정해준다.

 

이외에도 Filter에 @Order 애너테이션을 추가하거나 Order 인터페이스를 구현해서 Filter의 순서를 지정할 수 있다고 한다.

 

 

실행 결과

 

FilterConfiguration이 빈으로 등록되어있기 때문에 해당 어플리케이션을 실행하면 위와같이 필터들이 생성이된다. 생성 순서는 랜덤이며 크게 중요하지 않다.

 

 

이후 해당 어플리케이션에 요청을 보내게되면 위와 같은 결과가 나타난다.

 

사실 실험을 하기 이전, 이론적으로만 공부했을때에는 [첫번째 필터 실행 -> 첫번째 필터 종료 -> 두번째 필터 실행]과 같은 순서로 진행이 될줄 알았다. 

 

하지만 결과와 같이 필터들이 순차적으로 실행된 뒤, 컨트롤러가 실행되고 다시 역순으로 필터들이 종료되는 것을 확인할 수 있었다.

 

 

소스코드: https://github.com/Mason3144/templete-spring-security

 

'Java > Spring Security' 카테고리의 다른 글

JWT  (0) 2023.05.17
DelegatingPasswordEncoder  (0) 2023.05.15
SecurityFilterChain과 AuthenticationProvider 구현  (0) 2023.05.13
Spring Security의 인증 처리 흐름  (0) 2023.05.13
Spring Security Filter의 동작 흐름  (1) 2023.05.13