JWT(Json Web Token) - 2

수정이·2022년 8월 22일
0

security-jwt

목록 보기
6/7
post-thumbnail

Filter를 만들어보자

시큐리티를 통해 접근할 수 있는 URI를 걸러내기 전에 JWT를 통해서 해당 사용자를 인증해줘야한다. 그러기 위해서는 Filter Chain에 등록되어 있는 Spring Security보다 먼저 검증을 해야한다.
그래서 JWT를 만들어주는 필터를 만들어 볼 것이다.

우선 Filter 클래스를 만들어보고, 어떻게 동작하는지 살펴보자.

public class MyFilter1 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {

        System.out.println("필터1");
        chain.doFilter(request, response);
    }
}
public class MyFilter2 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {

        System.out.println("필터2");
        chain.doFilter(request, response);
    }
}
public class MyFilter3 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {

        System.out.println("필터3");
        chain.doFilter(request, response);
    }
}

일단 3개의 필터를 만들었다.
필터를 만들었을 때 가장 주의할 점은 꼭 chain.doFilter()를 호출해줘야 한다는 것이다.

만든 필터1, 2는 FilterConfig클래스를 통해 등록해보고 필터3은 SecurityConfig에 등록 시켜보자.

@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;
    }
}

두 필터는 모든 URL호출에 작동될 것이고, 숫자가 작은 것부터 실행될 것이다.

필터3을 등록시켜 보자.

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final CorsFilter corsFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        System.out.println("시큐리티 작동");
        http.addFilterBefore(new MyFilter3(), BasicAuthenticationFilter.class);
		
        (생략)
        
        return http.build();
    }
}

securityFilterChain가 실행되기 전에 필터3이 실행된다.
이제 실행시켜 보면 다음과 같이 실행된다.

필터3
필터1
필터2

이런 식으로 실행된다.


토큰을 만드는 필터 생성하기

필터1, 필터2는 그대로 냅두고 securityFilterChain이 실행되기 전에 실행되는 필터3을 토큰을 만들고 인증하는 필터로 만들어 볼 것이다.

public class MyFilter3 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        
        if (req.getMethod().equals("POST")) {
            System.out.println("POST 요청됨");
            String headerAuth = req.getHeader("Authorization");
            System.out.println(headerAuth);

            if (headerAuth.equals("cos")) {
                chain.doFilter(request, response);
            } else {
                res.getWriter().write("인증안됨");
            }
        }
    }
}

req.getHeader("Authorization)에 값이 우리가 원하는 토큰값이면
chain.doFilter(request, response)를 호출하여 컨트롤러까지 갈 수 있고,
우리가 원하는 토큰값이 아니면 "인증안됨"을 호출해준다는 의미이다.

클라이언트가 ID, PS를 정상적으로 넘겨주어 로그인이 완료되면 서버에서 토큰을 만들어주고 만든 토큰을 클라이언트에게 반환한다.
그 다음부터 클라이언트는 요청을 할 때마다 http header의 Authorization의 value값으로 토큰을 보낸다.
서버는 받은 토큰을 RSA or HS256을 통해 내가 만든 토큰이 맞는지 검증해주면 된다.


참고

스프링부트 시큐리티 & JWT 강의

0개의 댓글