👨‍👩‍👧‍👦 Project/📺 KIOSEK

JwtFilter에서 예외 발생시 JwtAuthenticationEntryPoint로 이어지지 않는 문제

DevPoong 2022. 11. 25. 01:31

1. 문제 상황

JwtTokenFilter를 UsernamePasswordAuthenticationFilter 이전에 끼워 넣고 실행하였는데 필터가 두 번 호출되고 동작이 꼬여버리는 상황이 발생했다. 

(1) JwtTokenFilter.java

@Component
@RequiredArgsConstructor
public class JwtTokenFilter extends OncePerRequestFilter {

    private final JwtTokenProvider jwtTokenProvider;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try{
            String jwt = resolveToken(request, AUTHORIZATION_HEADER);
            if (jwt != null && jwtTokenProvider.validateToken(jwt)) {
                Authentication authentication = jwtTokenProvider.getAuthentication(jwt);
                SecurityContextHolder.getContext().setAuthentication(authentication);
  				....
            }

        } catch(TokenNotPassedException e) {
            request.setAttribute("exception", e);
            log.info("catch token not passed exception");
        } catch (TokenNotBearerException e) {
            request.setAttribute("exception", e);
            log.info("TokenNotBearerException");
        } catch (SignatureException e) {
            request.setAttribute("exception", e);
            log.info("SignatureException");
        } catch (MalformedJwtException e) {
            request.setAttribute("exception", e);
            log.info("MalformedJwtException");
        } catch (ExpiredJwtException e) {
            request.setAttribute("exception", e);
            log.info("ExpiredJwtException");
        } catch (UnsupportedJwtException e) {
            request.setAttribute("exception", e);
            log.info("UnsupportedJwtException");
        } catch (JwtException | IllegalArgumentException e) {
            request.setAttribute("exception", e);
            log.info("JwtException | IllegalArgumentException");
        }

        filterChain.doFilter(request, response);
    }
	...
}

(2) SecurityConfig

public class SecurityConfig {
    private final JwtTokenProvider jwtTokenProvider;
    private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
    private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    ...
    
    ....
    
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                .authenticationEntryPoint(jwtAuthenticationEntryPoint) // 인증 실패시 오류 처리
                .accessDeniedHandler(jwtAccessDeniedHandler) // 권한 부족시 오류 처리
                .and()
                .apply(jwtTokenFilterConfig)
    			...
                .addFilterBefore(new JwtTokenFilter(jwtTokenProvider, ..), UsernamePasswordAuthenticationFilter.class)
                .build();

    }
}

 

2. 문제 해결

JwtTokenFilter에 생각 없이 @Component를 달고 SecurityConfig에서 new로 다시 생성해서 설정한 것이 문제였다.
@Component로 인해 어플리케이션 실행 시 필터에 자동 등록되었고 내가 한 번 더 생성해 버려서 꼬여버린 것이다.

결론
JwtTokenFilter에서 @Component를 삭제하면 된다!

 

정말 사소한 것이지만 중요한 부분을 놓치는 바람에 문제가 커져서 원인을 파악하는데만 하루종일 걸렸다..
이런 실수를 또 다시 하지 않기 위해 기록한다..