전체 개요

로그인 없이 사용자가 리퀘스트를 보내면?

  1. JwtAuthenticationFilter가 리퀘스트를 가로챔.
  2. 토큰이 없어서 인증에 실패. SecurityContext에 인증 정보가 없는 상태로 애플리케이션이 실행됨.

사용자가 로그인을 한다면?

  1. 위 1,2와 동일. 인증 정보가 없는 상태로 login 엔드포인트에 도달.
  2. AuthService에서 사용자 인증을 수행 하고 인증이 성공하면 JWT 토큰을 생성. 생성한 토큰을 사용자에게 전달.
  3. 사용자는 이후 리퀘스트 헤더에 jwt 토큰을 포함해서 전달.
  4. JwtAuthenticationFilter에선 토큰을 검증하고 사용자 정보를 추출.
  5. 추출된 정보로 Authentication 객체를 생성하고 SecurityContext에 저장.
  6. 나머지 로직에선 SecurityContext에 저장된 사용자 정보에 접근 가능.

JwtAuthenticationFilter

public class JwtAuthenticationFilter extends OncePerRequestFilter

Spring Security에서 JWT 기반 인증을 처리하는 데 사용되는 필터.

리퀘스트가 올 때 마다 JwtAuthenticationFilter가 가로채서 JWT를 검증하고, 인증 정보를 설정한다.

doFilterInternal

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)

모든 HTTP 요청에 대해 실행되는 핵심 메소드.

주요 동작 순서:
a) JWT 토큰 추출
getJwtFromRequest
리퀘스트 헤더에서 JWT 토큰을 추출한다.

b) 토큰 유효성 검사
tokenProvider.validateToken

c) 인증 정보 생성 및 설정
tokenProvider.getAuthenticationToken
유효한 토큰에서 인증 정보를 생성한다.

SecurityContextHolder.getContext().setAuthentication(authentication)
생성된 인증 정보를 Spring Security의 보안 컨텍스트에 설정한다.
이를 통해 현재 요청에 대한 사용자 인증 상태가 유지된다.

d) 다음 필터로 요청 전달
filterChain.doFilter

토큰이 없거나 유효하지 않은 경우

인증 정보가 설정 되지 않은 상태로 리퀘스트가 다음 필터로 전달된다.

보안상의 이점

매 요청마다 데이터베이스를 조회하지 않고 토큰만으로 인증을 처리한다.
Stateless 방식으로 서버의 부하를 줄이고 확장성을 높인다. (세션 방식과 다른 토큰 방식의 장점)

JwtTokenProvider

JWT(JSON Web Token)를 생성하고 검증하는 역할.

generateToken

Jwts.builder()
    .setSubject(userDetails.getUsername())  // 사용자 식별자 설정
    .claim("authorities", userDetails.getAuthorities().stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList()))  // 권한 정보 추가
    .setIssuedAt(now)  // 발급 시간
    .setExpiration(expiryDate)  // 만료 시간
    .signWith(jwtSecret)  // 비밀 키로 서명
    .compact();  // 토큰 생성

사용자 식별 (Subject):
데이터베이스 조회 없이 토큰만으로 사용자를 특정할 수 있게 하기 위함.

권한 정보 (Authorities):
데이터베이스 조회 없이 토큰만으로 권한 정보를 알 수 있게 하기 위함.
"authorities"라는 이름의 커스텀 클레임을 추가.
사용자의 모든 권한이 문자열 리스트 형태로 변환되어 전달 됨.

발급 시간과 만료 시간:
토큰의 유효 기간을 관리하여 보안을 강화.
만료된 토큰은 자동으로 거부.

서명:
토큰의 무결성을 보장.
클라이언트가 토큰을 임의로 변조할 수 없게 함.

CustomUserDetailsService

UserDetailsService 인터페이스를 구현하여 사용자 정보와 권한 정보를 제공하며, 이를 통해 Spring Security가 사용자 인증과 권한 부여를 수행할 수 있도록 함.

loadUserByUsername

Spring Security의 인증/인가에 필요한 정보를 담고 있는 User 객체를 생성하는 메서드.

UserDetails 객체 구성:

withUsername(user.getStudentId()): 사용자 식별자로 studentId를 사용.
password(user.getPassword()): 사용자의 암호화된 비밀번호를 설정.
authorities("ROLE_USER"): 모든 사용자에게 "ROLE_USER" 권한을 부여.

계정 상태 관련 설정:
accountExpired(false): 계정이 만료되지 않았음
accountLocked(false): 계정이 잠기지 않았음
credentialsExpired(false): 자격 증명(비밀번호)이 만료되지 않았음
disabled(false): 계정이 비활성화되지 않았음

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN