Hello

23. JWT Filter 등록 테스트

by 볼빵빵오춘기

MyFilter1.java

  • filter 패키지 만든 후 MyFilter1.java 생성 후 코드 작성한다. 
  • Filter를 implements 해준다.
  • doFilter()를 오버라이드 해주면 해당 클래스가 필터가 된다.
public class MyFilter1 implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("필터1"); // 실행이 됐는지 확인하기 위한 출력문

        // 필터체인에 등록하지않고 아래 주석처리 된부분처럼 적는다면 필터1이 걸리는 순간 프로그램이 그냥 끝난다. 그러므로 끝나지않고 계속 프로그램이 진행이 될려면 체인에 넘겨줘야한다.
        // PrintWriter out = response.getWriter();
        // out.print("안녕");
        chain.doFilter(request, response); // 필터체인에 등록을 해준다.=> 해주야지만 필터를 타라고 인지
    }
}

 

SecurityConfig.java - configure() 코드추가 (feat. 필터 걸어보기)

test

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilter(new MyFilter1()); // 에러

 

실행결과

Exception 발생한다. 

⇒ 니 필터는 SecurityFilterChain에 등록이 안돼! 니 필터는 타입이 Filter잖아 니 타입은 등록이 안돼. SecurityFilter만 등록이 되니깐 니가 필터를 등록하고 싶으면 addFilterBefore 이나 addFilterAfter 사용해!

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 com.cos.jwt.filter.MyFilter1 does not have a registered order and cannot be added without a specified order.
Consider using addFilterBefore or addFilterAfter instead.

 

해결

addFilterBefore()를 이용하여 필터 등록한다.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.addFilter(new MyFilter1()); // 에러
        http.addFilterBefore(new MyFilter1(), BasicAuthenticationFilter.class); // 필터가 실행되는지 test

 

실행화면

필터가 실행이 되어 “필터1”이 출력된다.

 

결과적으로

필터를 걸어서 필터가 실행되는 것을 확인했으나 필터를 걸 때 SecurityConfig에 필터를 걸 필요는 없다.

따로 필터를 걸 수 도 있다.

 

FilterConfig.java - SecurityConfig.java에 필터 걸지않고 따로 필터 걸어보기

test

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter1> filter1(){
        FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
        bean.addUrlPatterns("/*"); // "/*" 모든 요청에서 다해라
        bean.setOrder(0); // 낮은 번호가 필터 중에서 가장 먼저 실행됨
        return bean;
    }

}

 

실행화면

 

 

그러면 필터를 하나 더 만들고 싶다면..?

 

MyFilter2.java 생성 & FilterConfig.java 에 코드 추가

test

    @Bean
    public FilterRegistrationBean<MyFilter2> filter2(){
        FilterRegistrationBean<MyFilter2> bean = new FilterRegistrationBean<>(new MyFilter2());
        bean.addUrlPatterns("/*");
        bean.setOrder(0); 
        return bean;
    }

 

실행화면

필터1,2가 잘 실행되는 것을 확인된다.

⇒ 이것이 언제 동작하나? @Bean과 @Configuration 을 붙임으로써 IoC에 등록이 되어 요청이 올 때 실행이된다.

(IoC에 등록 부분 사실 @Bean을 붙여서인지 @Configuration을 붙여서 인건지 헷갈린다. 이 부분 IoC 등록 시점을 다시 한 번 체크하기)

⇒ filter1 과 filter2에 bean.setOrder(0) 코드가 있는데 이 코드는 실행 순서를 정하는 것이다.

숫자가 낮을 수록 더 빨리 실행된다. filter1에 bean.setOrder(0) 을 bean.setOrder(1) 로 변경해서 보면 확인이 가능하다.

 

 

test2

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter1> filter1(){
        FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
        bean.addUrlPatterns("/*"); // "/*" 모든 요청에서 다해라
        bean.setOrder(1); // 낮은 번호가 필터 중에서 가장 먼저 실행됨
        return bean;
    }

    @Bean
    public FilterRegistrationBean<MyFilter2> filter2(){
        FilterRegistrationBean<MyFilter2> bean = new FilterRegistrationBean<>(new MyFilter2());
        bean.addUrlPatterns("/*");
        bean.setOrder(0);
        return bean;
    }

}

 

실행화면2

 

MyFilter3.java & SecurityConfig.java - 내가 만든필터와 SecurityConfig의 필터 어떤 필터가 먼저 실행되는지 확인하기

test

MyFilter2.java 를 복사하여 MyFilter3.java 를 만든다.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
				http.addFilterBefore(new MyFilter3(), BasicAuthenticationFilter.class); // 필터1,2를 만들로 FilterConfig에서 만든 후 Security 필터가 먼저 실행되는지 아니면 내가 만든 필터가 먼저 실행되는지 test

 

실행화면


참고링크

https://velog.io/@sa833591/Spring-Security-5-Spring-Security-Filter-적용

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기