@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 Context
에 Authenication
의 형태로 담아서 공유해줘야 Spring Security
가 인가가 된 유저라는 것을 확인하고 OAuth를 다시 사용하지 않는다.