JwtTokenProvider라는 빈(Bean)을 생성하는 과정에서 BeanCreationException이 발생
문제의 핵심 :
JwtTokenProvider의 인스턴스화 실패
JwtTokenProvider 클래스의 생성자 내부에서 예외가 발생하는 경우application.properties 또는 application.yml)이 누락된 경우JWT 설정 추가: application.properties (또는 application.yml) 파일에 JWT 시크릿 키와 만료 시간을 정의하는 속성(예: jwt.secret=your-secret-key, jwt.expiration=86400000)을 추가
JwtTokenProvider 클래스 코드 수정 제안:
@Component 어노테이션을 사용하여 Spring이 이 클래스를 빈으로 관리@RequiredArgsConstructor (Lombok) 를 통해 의존성을 주입@Value 어노테이션을 사용하여 application.properties에 설정된 JWT 관련 값들(시크릿 키, 만료 시간)을 클래스 필드에 주입@PostConstruct 어노테이션이 붙은 메소드 내에서 시크릿 키를 Base64로 인코딩하여 보안을 강화createToken), 토큰으로부터 인증 정보 획득(getAuthentication), 토큰에서 사용자 이름 추출(getUsername), 권한 정보 추출(getAuthorities), 토큰 유효성 검증(validateToken) 등의 메소드 추가 @PostConstruct
protected void init() {
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
}
public String createToken(String username, List<String> roles) {
Claims claims = Jwts.claims().setSubject(username);
claims.put("roles", roles);
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(Keys.hmacShaKeyFor(secretKey.getBytes()))
.compact();
}
public Authentication getAuthentication(String token) {
String username = getUsername(token);
UserDetails userDetails = new User(username, "", getAuthorities(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getUsername(String token) {
return Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes()))
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
private Collection<? extends GrantedAuthority> getAuthorities(String token) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes()))
.build()
.parseClaimsJws(token)
.getBody();
List<String> roles = claims.get("roles", List.class);
return roles.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
public boolean validateToken(String token) {
try {
Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes()))
.build()
.parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}