spring.jwt.secret=afdsjlakfjskalrjkljsakrjaskldrl > 아무거나
@Component
public class JWTUtil {
private SecretKey secretKey;
// SecretKeySpec은 SecretKey를 생성하기 위한 구체적인 방법
public JWTUtil(@Value("${spring.jwt.secret}")String secret) {
secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), Jwts.SIG.HS256.key().build().getAlgorithm());
}
// JWT 토큰에서 username을 추출하는 메서드
// 토큰을 검증하고, 토큰 안에 담긴 정보를 파싱해서 가져옴
// 파싱된 내용 중 username 키 값을 찾아 사용자 이름을 반환!
public String getUsername(String token) {
return Jwts.parser().verifyWith(secretKey).build()
.parseSignedClaims(token).getPayload().get("username", String.class);
}
// Jwts는 JWT 처리 라이브러리에서 제공하는 클래스
// parser()는 토큰을 검증하고 파싱하는 메서드
// role을 추출
public String getRole(String token) {
return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get("role", String.class);
}
// JWT 토큰이 만료되었는지 체크 !
public Boolean isExpired(String token) {
return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().getExpiration().before(new Date());
}
// 새로운 JWT 토큰 생성 메소드
public String createJwt(String username, String role, Long expiredMs) {
return Jwts.builder()
.claim("username", username) // claim으로 추가!
.claim("role", role)
.issuedAt(new Date(System.currentTimeMillis())) // issuedAt()은 토큰 발급 시간
.expiration(new Date(System.currentTimeMillis() + expiredMs)) // expiration()은 만료 시간
.signWith(secretKey) // signWith(secretKey)는 비밀 키를 사용하여 서명을 하여 JWT 토큰을 생성
.compact();
} }
private final JWTUtil jwtUtil;
public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil) {
this.authenticationManager = authenticationManager;
this.jwtUtil = jwtUtil;
}
SecurityConfig에 JWTUtil 주입, Filter에도
private final JWTUtil jwtUtil;
public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil) {
this.authenticationConfiguration = authenticationConfiguration;
this.jwtUtil = jwtUtil;
}
//...
http
.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil), UsernamePasswordAuthenticationFilter.class);
성공시
//로그인 성공시 실행하는 메소드 (여기서 JWT를 발급하면 됨)
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) {
// 현재 인증된 사용자의 정보를 가져옴
CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
// 사용자 정보 추출
String username = customUserDetails.getUsername();
// 사용자 권한 추출
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
// iterator.next()를 통해 첫 번째 권한을 추출
GrantedAuthority auth = iterator.next();
// 문자열 형태로 가져온다 ROLE_ADMIN 처럼
String role = auth.getAuthority();
// JWT 생성
String token = jwtUtil.createJwt(username, role, 60*60*10L);
// JWT를 Response Header에 추가
response.addHeader("Authorization", "Bearer " + token);
}
//로그인 실패시 실행하는 메소드
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
response.setStatus(401);
}