diff --git a/.claude/settings.json b/.claude/settings.json index c1e2b5a..2bbd102 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -80,5 +80,8 @@ ] } ] + }, + "env": { + "CLAUDE_BOT_TOKEN": "ac15488ad66463bd5c4e3be1fa6dd5b2743813c5" } } diff --git a/src/main/java/com/gcsc/guide/auth/AuthController.java b/src/main/java/com/gcsc/guide/auth/AuthController.java index 45ee606..6d8cbb2 100644 --- a/src/main/java/com/gcsc/guide/auth/AuthController.java +++ b/src/main/java/com/gcsc/guide/auth/AuthController.java @@ -142,8 +142,10 @@ public class AuthController { }) @GetMapping("/check") public ResponseEntity checkProxyAuth(HttpServletRequest request, HttpServletResponse response) { + String targetUri = request.getHeader("X-Original-URI"); + String proxyCacheToken = getCookieValue(request, "gc_proxy_auth"); - if (jwtTokenProvider.validateProxyCacheToken(proxyCacheToken) != null) { + if (jwtTokenProvider.validateProxyCacheToken(proxyCacheToken, targetUri) != null) { return ResponseEntity.ok().build(); } @@ -154,7 +156,6 @@ public class AuthController { Long userId = jwtTokenProvider.getUserIdFromToken(sessionToken); String email = jwtTokenProvider.getEmailFromToken(sessionToken); - String targetUri = request.getHeader("X-Original-URI"); User user = userRepository.findByIdWithRoles(userId).orElse(null); if (user == null || user.getStatus() != com.gcsc.guide.entity.UserStatus.ACTIVE) { @@ -166,7 +167,7 @@ public class AuthController { return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); } - String cacheToken = jwtTokenProvider.generateProxyCacheToken(userId); + String cacheToken = jwtTokenProvider.generateProxyCacheToken(userId, targetUri); ResponseCookie cacheCookie = ResponseCookie.from("gc_proxy_auth", cacheToken) .path("/") .httpOnly(true) diff --git a/src/main/java/com/gcsc/guide/auth/JwtTokenProvider.java b/src/main/java/com/gcsc/guide/auth/JwtTokenProvider.java index 518b990..0c2b369 100644 --- a/src/main/java/com/gcsc/guide/auth/JwtTokenProvider.java +++ b/src/main/java/com/gcsc/guide/auth/JwtTokenProvider.java @@ -68,26 +68,34 @@ public class JwtTokenProvider { return expirationMs; } - public String generateProxyCacheToken(Long userId) { + public String generateProxyCacheToken(Long userId, String targetUri) { long expiry = Instant.now().plusMillis(expirationMs).getEpochSecond(); - String payload = userId + ":" + expiry; + String uriHash = hmacSha256(targetUri != null ? targetUri : ""); + String payload = userId + ":" + uriHash + ":" + expiry; String hmac = hmacSha256(payload); return payload + ":" + hmac; } - public Long validateProxyCacheToken(String token) { + public Long validateProxyCacheToken(String token, String targetUri) { if (token == null || token.isBlank()) { return null; } try { String[] parts = token.split(":"); - if (parts.length != 3) { + if (parts.length != 4) { return null; } long userId = Long.parseLong(parts[0]); - long expiry = Long.parseLong(parts[1]); - String expectedHmac = hmacSha256(userId + ":" + expiry); - if (!expectedHmac.equals(parts[2])) { + String uriHash = parts[1]; + long expiry = Long.parseLong(parts[2]); + + String expectedUriHash = hmacSha256(targetUri != null ? targetUri : ""); + if (!expectedUriHash.equals(uriHash)) { + return null; + } + + String expectedHmac = hmacSha256(userId + ":" + uriHash + ":" + expiry); + if (!expectedHmac.equals(parts[3])) { return null; } if (Instant.now().getEpochSecond() > expiry) {