Spring Security JWT Filter 등록

바그다드·2023년 4월 18일
0

Spring Security

목록 보기
13/17
  • 지난번까지 해서 Security 설정을 마쳤다. 이제 filter를 생성하고 등록해보자!

MyFilter.java 생성

  • filter 패키지를 생성하여 클래스를 생성해주자
package com.pem.jwt.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter1 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("필터1");
        // 여기서 response를 이용해 응답을 보내버리면 프로세스가 끝나버리기 때문에
        // 프로세스를 진행하기 위해 다시 필터에 요청과 응답을 넘겨줘야 한다.
        chain.doFilter(request, response);
    }
}

SecurityConfig.java 수정

  • 이제 filter를 등록해주자
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		// 아래 한 줄만 추가 됨
        http.addFilterBefore(new MyFilter1(), BasicAuthenticationFilter.class);
        return http
                .csrf().disable()
  • 그런데 filterChain의 리턴 타입은 SecurityFilterChain으로 Filter와 리턴 타입이 달라 에러가 발생한다. 이를 위해 addFilterBefore 또는 addFilterAfter를 이용하여 BasicAuthenticationFilter가 등록되기 전에 MyFilter1를 먼저 등록해주자!
    그리고 localhost:8080/home으로 접근한 뒤, 콘솔을 확인해보면 필터가 등록되어 있는 것을 확인할 수 있다.
  • 그런데 FilterChain에 필터를 등록하는 방법 뿐만 아니라 따로 걸어주는 방법도 해보자.

SecurityConfig.java 수정

SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .csrf().disable()
  • 필터 등록 코드를 제거해주자

FilterConfig 생성

package com.pem.jwt.config;

import com.pem.jwt.filter.MyFilter1;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter1> filter1() {
        FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
        bean.addUrlPatterns("/*");
        // 필터의 우선순위를 정하는 메소드
        // 숫자가 낮을 수록 우선순위는 높다.
        bean.setOrder(0);
        return bean;
    }
}
  • FilterRegistrationBean을 이용해 MyFilter1을 빈으로 등록하고, 필터를 적용할 url을 설정해주자
  • 그리고 다시 home으로 접근하면 필터가 적용되어 있는 것을 확인할 수 있다.
  • 필터를 추가로 등록해보자

MyFilter2 생성

package com.pem.jwt.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter2 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("필터2");
        // 여기서 response를 이용해 응답을 보내버리면 프로세스가 끝나버리기 때문에
        // 프로세스를 진행하기 위해 다시 필터에 요청과 응답을 넘겨줘야 한다.
        chain.doFilter(request, response);
    }
}
  • MyFilter1을 복사하여 이름을 변경하고, 코드도 숫자만 변경해주자

FilterConfig 수정

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter1> filter1() {
        FilterRegistrationBean<MyFilter1> bean = new FilterRegistrationBean<>(new MyFilter1());
        bean.addUrlPatterns("/*");
        // 필터의 우선순위를 정하는 메소드
        // 숫자가 낮을 수록 우선순위는 높다.
        bean.setOrder(0);
        return bean;
    }

    @Bean
    public FilterRegistrationBean<MyFilter2> filter2() {
        FilterRegistrationBean<MyFilter2> bean = new FilterRegistrationBean<>(new MyFilter2());
        bean.addUrlPatterns("/*");
        // 필터의 우선순위를 정하는 메소드
        // 숫자가 낮을 수록 우선순위는 높다.
        bean.setOrder(1);
        return bean;
    }
}
  • FilterConfig에 filter2를 추가로 등록해줬다. 그리고 다시 home으로 등록해주면 필터가 정상적으로 등록되어 있는 것을 확인할 수 있다.
  • 그럼 SecurityFilterChain이 먼저 등록이 될까? 내가 생성한 필터가 먼저 등록이 될까? 확인해보자

MyFilter3 생성

package com.pem.jwt.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter3 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("필터3");
        // 여기서 response를 이용해 응답을 보내버리면 프로세스가 끝나버리기 때문에
        // 프로세스를 진행하기 위해 다시 필터에 요청과 응답을 넘겨줘야 한다.
        chain.doFilter(request, response);
    }
}

SecurityConfig.java 수정

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new MyFilter1(), BasicAuthenticationFilter.class);
        return http
                .csrf().disable()
  • 이번에는 SecurityFilterChain이 먼저 등록되는지, 내가 만든 필터가 먼저 등록이 되는지 확인해보기 위해 MyFilter3를 생성해서 SecurityFilterChain에 등록해줬다. 그리고 home으로 접근해서 우선순위를 확인해보자
  • 위에 보이는 것처럼 SecurityFilterChain이 먼저 등록되는 것을 확인할 수 있다.
    참고로, addFilterBefore대신에 addFilterAfter를 사용해도 결과는 똑같이 나온다.
  • 그렇다면 모든 필터중에 내가 정의한 필터가 가장 먼저 동작하게 하고 싶다면?
@Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new MyFilter3(), SecurityContextPersistenceFilter.class);
        return http
                .csrf().disable()
  • 이렇게 정의하면 눈에 띄지는 않지만 내가 정의한 filter가 가장 먼저 동작하게 된다!!
profile
꾸준히 하자!

0개의 댓글