▶ JwtFilter 클래스
@Slf4j
@RequiredArgsConstructor
public class JwtFilter extends GenericFilterBean {
public static final String AUTHORIZATION_HEADER = "Authorization";
private final TokenProvider tokenProvider;
...
}
- @Slf4j: Lombok의 어노테이션으로, log 객체를 자동으로 생성한다. 이 객체는 로깅을 위해 사용된다. 코드 내에서 로깅을 통해 디버깅이나 오류 메시지를 기록할 수 있다.
- @RequiredArgsConstructor: Lombok의 어노테이션으로, final로 선언된 필드를 포함하는 생성자를 자동으로 생성한다. 이를 통해 TokenProvider를 생성자 주입 방식으로 사용할 수 있다.
- public class JwtFilter extends GenericFilterBean: JwtFilter 클래스는 Spring의 GenericFilterBean을 상속받아 요청 처리 필터를 정의한다. 이 필터는 HTTP 요청을 가로채고 JWT를 검증하는 역할을 한다.
- public static final String AUTHORIZATION_HEADER = "Authorization";: HTTP 요청 헤더에서 JWT 토큰을 찾기 위해 사용할 상수다. 기본적으로 JWT는 Authorization 헤더에 담겨 전송된다.
- private final TokenProvider tokenProvider;: JWT의 생성, 검증 및 인증 정보를 제공하는 TokenProvider 객체를 필드로 선언한다. final로 선언되어 초기화 이후 변경할 수 없다.
▶ doFilter 메소드
더보기
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String jwt = resolveToken(httpServletRequest);
String requestURI = httpServletRequest.getRequestURI();
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
Authentication authentication = tokenProvider.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
log.debug("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}",
authentication.getName(), requestURI);
} else {
log.debug("유효한 JWT 토큰이 없습니다, uri: {}", requestURI);
}
filterChain.doFilter(servletRequest, servletResponse);
}
▷ doFilter 메소드 해석
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
- @Override: GenericFilterBean의 doFilter 메소드를 재정의한다. 이 메소드는 요청을 필터링하고 다음 필터로 요청을 전달하는 역할을 한다.
- ServletRequest servletRequest: 클라이언트의 요청 정보를 포함한다.
- ServletResponse servletResponse: 서버의 응답 정보를 포함한다.
- FilterChain filterChain: 다음 필터로 요청을 전달하는 역할을 한다.
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String jwt = resolveToken(httpServletRequest);
String requestURI = httpServletRequest.getRequestURI();
- HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;: ServletRequest를 HttpServletRequest로 형변환하여 HTTP 요청 정보를 다룰 수 있게 한다.
- String jwt = resolveToken(httpServletRequest);: resolveToken 메소드를 호출하여 HTTP 요청에서 JWT 토큰을 추출한다.
- String requestURI = httpServletRequest.getRequestURI();: 요청 URI를 가져온다. 이는 로깅에 사용될 수 있다.
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
Authentication authentication = tokenProvider.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
log.debug("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}",
authentication.getName(), requestURI);
- if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)): JWT가 유효한지 검사한다. StringUtils.hasText(jwt)는 JWT가 비어 있지 않은지 확인하고, tokenProvider.validateToken(jwt)는 토큰의 유효성을 검증한다.
- Authentication authentication = tokenProvider.getAuthentication(jwt);: JWT를 사용하여 Authentication 객체를 가져온다. 이 객체는 사용자 인증 정보를 담고 있다.
- SecurityContextHolder.getContext().setAuthentication(authentication);: 인증 정보를 SecurityContext에 설정하여, 이후의 요청 처리에서 사용될 수 있게 한다.
- log.debug("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", authentication.getName(), requestURI);: 인증 정보가 SecurityContext에 저장되었음을 로그로 기록한다.
} else {
log.debug("유효한 JWT 토큰이 없습니다, uri: {}", requestURI);
}
- JWT가 없거나 유효하지 않을 경우, 해당 내용을 로그로 기록한다.
filterChain.doFilter(servletRequest, servletResponse);
- filterChain.doFilter(servletRequest, servletResponse);: 요청을 다음 필터로 전달한다. 필터 체인에서 다음 단계의 필터가 호출된다.
▶ resolveToken 메소드
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
- private String resolveToken(HttpServletRequest request): HTTP 요청에서 JWT 토큰을 추출하는 메소드다.
- String bearerToken = request.getHeader(AUTHORIZATION_HEADER);: 요청 헤더에서 Authorization 값을 가져온다.
- if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")): 가져온 토큰이 비어 있지 않고 Bearer 로 시작하는지 확인한다.
- return bearerToken.substring(7);: Bearer 이후의 실제 JWT 토큰을 반환다. Bearer 라는 문자열의 길이는 7자이므로, 이를 잘라내어 반환한다.
- return null;: 유효한 JWT 토큰이 없으면 null을 반환한다.
'개인 코드 분석' 카테고리의 다른 글
스프링 시큐리티 Jwt: jwt.SecurityConfig (0) | 2024.11.05 |
---|---|
스프링 시큐리티 Jwt: jwt.JwtSecurityConfig (0) | 2024.11.05 |
스프링 시큐리티 Jwt: jwt.JwtAuthenticationEntryPoint (0) | 2024.11.05 |
스프링 시큐리티 Jwt: jwt.JwtAccessDeniedHandler (0) | 2024.11.05 |
스프링 시큐리티 Jwt: handler.GlobalExceptionHandler (0) | 2024.11.05 |