@Component
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {

	private final JwtProvider jwtProvider;
	private final UserQueryPort userQueryPort;

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
		FilterChain filterChain) throws ServletException, IOException {
		String accessToken = AuthorizationExtractor.extract(request);
		Date now = new Date();

		if (!StringUtils.hasText(accessToken)) {
			doFilter(request, response, filterChain);
			return;
		}

		verifyToken(accessToken, now);
		User user = userQueryPort.findById(jwtProvider.getPayload(accessToken));

		Authentication auth = getAuthentication(user);
		SecurityContextHolder.getContext().setAuthentication(auth);

		filterChain.doFilter(request, response);
	}

	private void verifyToken(String accessToken, Date now) {
		if (!jwtProvider.verifyToken(accessToken, now)) {
			throw new GoHigherException(AuthErrorCode.TOKEN_EXPIRED);
		}
	}

	public Authentication getAuthentication(User user) {
		return new UsernamePasswordAuthenticationToken(user, "",
			List.of(new RoleGrantedAuthority(user.getRole())));
	}
}

해당 필터를 만들어서 oauth가 실행되기 전에 필터를 위치시킨다. 해당 필터의 위치는 SecurityConfig에 하단 부분이다.

이 부분은 Spring Security를 사용하지 않더라도 우리가 늘 사용했던 인가 부분이고 한 가지만 다르다. 하나 알아둬야 할 것은 인가가 됐다면(로그인한 유저이기 때문에 요청이 허용된다면) Security ContextAuthenication의 형태로 담아서 공유해줘야 Spring Security가 인가가 된 유저라는 것을 확인하고 OAuth를 다시 사용하지 않는다.