Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

JAN's History

JWT를 구현하기전, Filter 등록 테스트 본문

JWT

JWT를 구현하기전, Filter 등록 테스트

JANNNNNN 2024. 7. 4. 16:51

Spring Security Filter Chain

필터를 등록하기 전, 스프링에서 제공하는 Filter Chain에 대해 꼭 알아두기를 바랍니다!

이전 글에 정리해뒀으니 읽어보고 오시는 것을 추천드려요 :)

Filter 생성하기

public class MyFilter1 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter 1");
        filterChain.doFilter(servletRequest, servletResponse);  // 다음 필터로 넘어가라는 의미
    }
}

Servlet 아래에 있는 Filter 인터페이스를 구현해줍니다.

해당 필터에서 처리하고 다음 필터로 넘겨주는 doFilter를 꼭 오버라이드 해줘야해요.

Filter 등록

  • addFilter(Filter filter)
  • addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)
  • addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) 
http.addFilter(new MyFilter1());

생성한 필터를 등록하기 위해 addFilter(new MyFilter1());을 하게 되면 에러 메시지가 발생하는데요!

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: The Filter class me.iseunghan.jwttutorial.filter.MyFilter1 does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.

MyFilter1은 SpringSecurityFilterChain에 등록되지 않았으니 등록하고 싶으면 addFilterBefore or addFilterAfter를 사용하라는 뜻입니다.

 

addFilterBefore

http.addFilterBefore(new MyFilter1(), UsernamePasswordAuthenticationFilter.class); 

UsernamePasswordAuthenticationFilter 직전에 MyFilter가 걸리도록 합니다.

 

addFilterBefore

http.addFilterAfter(new MyFilter1(), UsernamePasswordAuthenticationFilter.class); 

 

UsernamePasswordAuthenticationFilter 이후에 MyFilter가 걸리도록 합니다.

FilterConfig 생성

굳이 SecurityConfig에 추가하지 않고도 따로 FilterConfig를 생성해 등록하는 방법도 있어요.

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter1> filter1() {
        FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
        bean.addUrlPatterns("/*");  // 모든 요청에 대해서 필터 적용
        bean.setOrder(0);   // 낮은 숫자일수록 우선순위

        return bean;
    }
}

SpringSecurityFilter가 먼저 생성될지 Vs 우리가 생성한 MyFilter가 먼저 실행될지???

테스트 환경

  • MyFilter1 과 MyFilter2, MyFilter3를 생성
  • MyFilter1,2는 FilterConfig에 등록! (위 코드와 동일 : 우선순위 0으로 설정)
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter1> filter1() {
		...
        bean.setOrder(0);   // 낮은 숫자일수록 우선순위
		.. 
  • MyFilter3는 SecurityConfig에 등록! (Username..Filter 이전에 실행되도록 설정)
http.addFilterBefore(new MyFilter2(), UsernamePasswordAuthenticationFilter.class)

실행 결과

SecurityConfig에 등록한 Filter3이 먼저 실행되고, 이후에 Filter 3 > 2 > 1 순으로 실행되었다.

SpringSecurityFilter에 특정 필터보다 먼저 실행되게 하기 위해선

SecurityConfig 설정에 필터를 등록하자!

  • addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)
  • addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)