들어가면서

외부에서 특정한 API를 호출할때 반드시 인증에 사용할 토큰을 같이 전송하고, 서버에서는 이를 검증한다. 이 과정에서 특정한 URL을 호출할때 전달된 토큰을 검사하는 필터가 사용된다. 스프링 시큐리티는 원하는 필터를 사용자가 작성하고, 이를 설정에서 시큐리티 동작의 일부로 추가할수 있다.

OncePerRequestFilter

매번 동작하는 기본적일 필터, 주로 상속해서 많이 사용된다.

디렉토리 설정을 아래와 같이 설정 후, 소스를 아래와 같이 구성한다.

디렉토리설정

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Log4j2
public class ApiCheckFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("API Check Filter.....");
        filterChain.doFilter(request, response);
    }
}

//SecurityConfig에 Bean으로 등록한다.

    @Bean
    public ApiCheckFilter apiCheckFilter(){
        return new ApiCheckFilter();
    }

GET으로 접근 가능한 요청을 하면 아래와 같이 필터가 작동한다. 그리고 스프링 시큐리티의 여러 필터 중 가장 마자막 필터로 동작하는것을 알 수 있다. 커스텀필터1

필터의 위치 조절과 AntPathMatcher

ApiCheckFilter의 동작 순서를 조절하고 싶다면, 기존에 있는 특정한 필터의 이전이나 다음에 동작하도록 할 수 있다. 예를 들어, UsernamePassword AuthenticationFilter는 사용자의 아이디와 패스워드를 기반으로 동작하는 필터인데, 이 필터 수행 전에 동작하도록 지정할 수 있다.

 @Override
    protected void configure(HttpSecurity http) throws Exception{
        ...

        http.addFilterBefore(apiCheckFilter(), UsernamePasswordAuthenticationFilter.class);
    }

커스텀필터2

만약 특정 경로에 올때만 필터를 걸어주고 싶을땐, AntPathMatcher를 사용한다. 이는 중간에 ?,*,**와 같은 기호를 사용해서 패턴이 맞는지 검사한다.

    @Bean
    public ApiCheckFilter apiCheckFilter(){
        return new ApiCheckFilter("/notes/**/*");
    }


@Log4j2
public class ApiCheckFilter extends OncePerRequestFilter {

    private AntPathMatcher antPathMatcher;
    private String pattern;

    public ApiCheckFilter(String pattern){
        this.antPathMatcher = new AntPathMatcher();
        this.pattern = pattern;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("REQUEST URI: " + request.getRequestURI());
        log.info(antPathMatcher.match(pattern,request.getRequestURI()));
        if(antPathMatcher.match(pattern,request.getRequestURI())){
            log.info("API Check Filter........");
            return;
        }

        filterChain.doFilter(request, response);
    }
}

커스텀필터2