Back-end/Spring-핵심& webMVC

Spring Filter, Interceptor의 범위 및 SpringSecurity FilterChain와의 관계

prden 2023. 1. 18. 21:25

0. Servlet Filter VS.  HandlerInterceptor

아래 그림에서와 같이 Filter는 DispatcherSevlet 앞에서 먼저 동작한다. 

Interceptor는 Dispatcher Servlet에서 Controller(Handler)사이에서 동작한다. 

 

 1) 필터 

  • 웹 어플리케이션의 Context 역할
  • 스프링 기능을 활용하기 어려움
  • 일반적으로 인코딩, CORS, XSS, LOG, 인증, 권한 등을 구현

 

 2) 인터셉터

  • 스프링의 Spring Context의 기능이며 일종의 빈
  • 스프링 컨테이너여서 다른 빈을 주입하여 활용성이 좋다. 
  • 다른빈을 활용할 수 있어 보통 인증, 권한 등 구현함

 

1. JwtFilter에서 OncePerRequestFilter 상속 VS GenericFilterBean 또는GenericFilterBean상속받은 AbstractAuthenticationProcessingFilter차이

 

1) OncePerRequestFilter : 요청 당 단 한번의 실행을 보장한다. 아래의 그림과 같이 4) 다시 first, second filter를 타지 않고 

first, second filter는 한 번만 탄다. 예를 들어 인증처리를 할 경우 아래와 같이 두 번 first, second filter를 타면 불필요한 처리를 반복하게 된다. 

https://dev-racoon.tistory.com/34

public class JwtFilter extends OncePerRequestFilter {
    private static final Logger logger = LogManager.getLogger(JwtFilter.class);

    public static final String AUTHORIZATION_HEADER = "Authorization";

    private TokenProvider tokenProvider;

    public JwtFilter(TokenProvider tokenProvider) {
        this.tokenProvider = tokenProvider;
    }

    // 포함하지 않을 url
    private static final List<String> EXCLUDE_URL =
            Collections.unmodifiableList(
                    Arrays.asList(
                            "/static/**",
                            "/favicon.ico",
                            "/admin",
                            "/api/signIn",
                            "/api/signUp",
                            "/admin/signIn",
                            "/admin/signUp"
                    ));

    // jwt의 인증정보를 현재 실행중인 SecurityContext에 저장하는 역할 수행

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String jwt = resolveToken(request);
        String requestURI = request.getRequestURI();

        // Request Header에서 jwt를 꺼내오고 그 jwt가 유효하면
        if(StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
            Authentication authentication = tokenProvider.getAuthentication(jwt);
            // securityContext에 저장한다.
            SecurityContextHolder.getContext().setAuthentication(authentication);
            logger.debug("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", authentication.getName(), requestURI);
        } else {
            logger.debug("유효한 JWT 토큰이 없습니다, uri: {} ", requestURI);
        }
        filterChain.doFilter(request, response);

    }

    //Request Header에서 토큰 정보를 꺼내오기 위한 resolverToken 메소드
    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
        if(StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request){
        return EXCLUDE_URL.stream().anyMatch(exclude -> exclude.equalsIgnoreCase(request.getServletPath()));
    }
}

 

2. SpringSecurity에서의 FilterChain과  Servlet의 Filter

https://velog.io/@seongwon97/Spring-Security-Filter%EB%9E%80

 

[Spring Security] Filter란?

Spring Security의 Filter에 관한 전반적인 설명입니다.

velog.io

SecurityFilterChain

https://velog.io/@kose/SecurityFilterChain-%EB%8B%A4%EC%A4%91-%ED%95%84%ED%84%B0-%EA%B4%80%EB%A6%AC

 

SecurityFilterChain 다중 필터 관리

안녕하세요.! 개발이 즐거운 코세입니다.!이번 포스팅은 SecurityFilterChain에 대해 탐구해본 내용을 정리하여 작성하겠습니다.!SecurityFilterChain을 이해하는 데 도움이 될 수 있는 두 가지 사진을 먼저

velog.io