86 lines
2.9 KiB
Java
86 lines
2.9 KiB
Java
package com.goi.erp.token;
|
|
|
|
import io.jsonwebtoken.Claims;
|
|
import io.jsonwebtoken.Jwts;
|
|
import io.jsonwebtoken.security.Keys;
|
|
import org.springframework.data.domain.AuditorAware;
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* auth-service에서 발급한 JWT 토큰 기반으로 현재 사용자(empId)를 가져오는 AuditorAware 구현체
|
|
*
|
|
* - JPA auditing에서 사용자가 누군지 기록할 때 사용
|
|
* - SecurityContextHolder 없이도 동작 가능
|
|
* - HttpServletRequest에서 Authorization 헤더를 읽어 토큰 파싱
|
|
*/
|
|
public class ApplicationAuditAware implements AuditorAware<Integer> {
|
|
|
|
private final String jwtSecret;
|
|
|
|
public ApplicationAuditAware(String jwtSecret) {
|
|
this.jwtSecret = jwtSecret;
|
|
}
|
|
|
|
/**
|
|
* 현재 요청을 수행하는 사용자의 empId 반환
|
|
* @return Optional<Integer> - empId가 없거나 토큰이 유효하지 않으면 Optional.empty()
|
|
*/
|
|
@Override
|
|
public Optional<Integer> getCurrentAuditor() {
|
|
HttpServletRequest request = getCurrentHttpRequest();
|
|
if (request == null) {
|
|
return Optional.empty();
|
|
}
|
|
|
|
String token = resolveToken(request);
|
|
if (token == null) {
|
|
return Optional.empty();
|
|
}
|
|
|
|
try {
|
|
// JWT 파싱
|
|
Claims claims = Jwts.parserBuilder()
|
|
// HMAC SHA 키 객체 생성 (secret 길이와 안전성 체크)
|
|
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8)))
|
|
.build()
|
|
.parseClaimsJws(token)
|
|
.getBody();
|
|
|
|
// 토큰에 empId 클레임이 있어야 함
|
|
Integer empId = claims.get("empId", Integer.class);
|
|
return Optional.ofNullable(empId);
|
|
} catch (Exception e) {
|
|
// 토큰 파싱/검증 실패 시 Optional.empty() 반환
|
|
return Optional.empty();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 현재 스레드의 HttpServletRequest 가져오기
|
|
* @return HttpServletRequest 또는 null
|
|
*/
|
|
private HttpServletRequest getCurrentHttpRequest() {
|
|
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
if (attrs == null) return null;
|
|
return attrs.getRequest();
|
|
}
|
|
|
|
/**
|
|
* HttpServletRequest에서 Authorization 헤더의 Bearer 토큰 추출
|
|
* @param request 현재 HttpServletRequest
|
|
* @return JWT 문자열 또는 null
|
|
*/
|
|
private String resolveToken(HttpServletRequest request) {
|
|
String bearerToken = request.getHeader("Authorization");
|
|
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
|
return bearerToken.substring(7);
|
|
}
|
|
return null;
|
|
}
|
|
}
|