로그인 없이 사용자가 리퀘스트를 보내면?
사용자가 로그인을 한다면?
public class JwtAuthenticationFilter extends OncePerRequestFilter
Spring Security
에서 JWT 기반 인증을 처리하는 데 사용되는 필터.
리퀘스트가 올 때 마다 JwtAuthenticationFilter
가 가로채서 JWT를 검증하고, 인증 정보를 설정한다.
@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 방식으로 서버의 부하를 줄이고 확장성을 높인다. (세션 방식과 다른 토큰 방식의 장점)
JWT(JSON Web Token)를 생성하고 검증하는 역할.
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"라는 이름의 커스텀 클레임을 추가.
사용자의 모든 권한이 문자열 리스트 형태로 변환되어 전달 됨.
발급 시간과 만료 시간:
토큰의 유효 기간을 관리하여 보안을 강화.
만료된 토큰은 자동으로 거부.
서명:
토큰의 무결성을 보장.
클라이언트가 토큰을 임의로 변조할 수 없게 함.
UserDetailsService
인터페이스를 구현하여 사용자 정보와 권한 정보를 제공하며, 이를 통해 Spring Security
가 사용자 인증과 권한 부여를 수행할 수 있도록 함.
Spring Security
의 인증/인가에 필요한 정보를 담고 있는 User 객체를 생성하는 메서드.
UserDetails
객체 구성:
withUsername(user.getStudentId()): 사용자 식별자로 studentId를 사용.
password(user.getPassword()): 사용자의 암호화된 비밀번호를 설정.
authorities("ROLE_USER"): 모든 사용자에게 "ROLE_USER" 권한을 부여.
계정 상태 관련 설정:
accountExpired(false): 계정이 만료되지 않았음
accountLocked(false): 계정이 잠기지 않았음
credentialsExpired(false): 자격 증명(비밀번호)이 만료되지 않았음
disabled(false): 계정이 비활성화되지 않았음