diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/common/CookieHelper.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/common/CookieHelper.java index 9f89197..a2b6ae2 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/common/CookieHelper.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/common/CookieHelper.java @@ -8,6 +8,14 @@ import org.springframework.web.context.request.ServletRequestAttributes; import java.util.Optional; public class CookieHelper { + + public static Cookie createCookie(String cookieName, String cookieValue) { + Cookie jwtCookie = new Cookie(cookieName, cookieValue); + jwtCookie.setHttpOnly(true); + jwtCookie.setPath("/"); + return jwtCookie; + } + public static Optional getValueFromCookieWithName(String name) { ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = attr.getRequest(); diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/filter/LoggingFilter.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/filter/LoggingFilter.java index 995a6aa..fdacfa7 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/filter/LoggingFilter.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/filter/LoggingFilter.java @@ -5,6 +5,7 @@ import com.bpgroup.poc.admin.common.CookieHelper; import com.bpgroup.poc.admin.common.JwtHelper; import com.bpgroup.poc.admin.security.jwt.JwtTokenConstants; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -50,7 +51,7 @@ public class LoggingFilter extends OncePerRequestFilter { private void loggingRequest(ContentCachingRequestWrapper request, String sessionId) { String requestValue = new String(request.getContentAsByteArray(), StandardCharsets.UTF_8); - Optional jwtToken = CookieHelper.getValueFromCookieWithName(request, JwtTokenConstants.NAME); + Optional jwtToken = CookieHelper.getValueFromCookieWithName(request, JwtTokenConstants.ACCESS_TOKEN); if (jwtToken.isPresent()) { try { @@ -65,19 +66,21 @@ public class LoggingFilter extends OncePerRequestFilter { username ) ); + } catch (ExpiredJwtException e) { + log.info("SESSION ID: {} Request - JWT 토큰 만료", sessionId); } catch (Exception e) { - log.info("session ID: {} Request - JWT 토큰 만료", sessionId); + log.error("SESSION ID: {} Request - JWT 토큰 검증 실패", sessionId); } } - log.info("session ID: {} Request - method: {} uri: {}", sessionId, request.getMethod(), request.getRequestURI()); - log.info("session ID: {} Request - params: {}", sessionId, requestValue); + log.info("SESSION ID: {} Request - method: {} uri: {}", sessionId, request.getMethod(), request.getRequestURI()); + log.info("SESSION ID: {} Request - params: {}", sessionId, requestValue); } private void loggingResponse(ContentCachingResponseWrapper response, String sessionId) { String contentType = response.getContentType(); - log.info("Session ID: {} Response - status: {} Content-Type: {}", sessionId, response.getStatus(), contentType); + log.info("SESSION ID: {} Response - status: {} Content-Type: {}", sessionId, response.getStatus(), contentType); if (contentType != null && isLoggingContentType(contentType)) { String responseValue = new String(response.getContentAsByteArray(), StandardCharsets.UTF_8); @@ -89,7 +92,7 @@ public class LoggingFilter extends OncePerRequestFilter { ) ); - log.info("Session ID: {} Response - body: {}", sessionId, responseValue); + log.info("SESSION ID: {} Response - body: {}", sessionId, responseValue); } } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java index c622deb..6964a74 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/SecurityConfig.java @@ -1,8 +1,6 @@ package com.bpgroup.poc.admin.security; -import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationEntryPoint; -import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationFilter; -import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationProvider; +import com.bpgroup.poc.admin.security.authentication.*; import com.bpgroup.poc.admin.app.authentication.AuthenticationService; import com.bpgroup.poc.admin.security.authorization.CustomAccessDeniedHandler; import com.bpgroup.poc.admin.security.authorization.CustomAuthorizationManager; @@ -81,7 +79,7 @@ public class SecurityConfig { http.logout(c -> c .logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_PATH, "GET")) .logoutSuccessUrl(LOGIN_PATH) - .deleteCookies(JwtTokenConstants.NAME) + .deleteCookies(JwtTokenConstants.ACCESS_TOKEN) ); return http.build(); @@ -103,6 +101,8 @@ public class SecurityConfig { public CustomAuthenticationFilter authenticationGenerateFilter() { CustomAuthenticationFilter filter = new CustomAuthenticationFilter(); filter.setAuthenticationManager(authenticationManager()); + filter.setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler()); + filter.setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler()); return filter; } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationEntryPoint.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationEntryPoint.java index 0b7fd59..bba9b95 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationEntryPoint.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationEntryPoint.java @@ -18,7 +18,7 @@ import java.util.Optional; public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - Optional jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.NAME); + Optional jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.ACCESS_TOKEN); if (jwtToken.isPresent()) { response.sendRedirect("/login?error=" + URLEncoder.encode("로그인 세션이 만료되었습니다. 다시 로그인 해주세요.", StandardCharsets.UTF_8)); } else { diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationFilter.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationFilter.java index 6870e4e..122a80d 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationFilter.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationFilter.java @@ -24,8 +24,6 @@ public class CustomAuthenticationFilter extends AbstractAuthenticationProcessing public CustomAuthenticationFilter() { super(new AntPathRequestMatcher(DEFAULT_LOGIN_REQUEST_URL, HTTP_METHOD)); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다. - setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler()); - setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler()); } @Override diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationSuccessHandler.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationSuccessHandler.java index fa4f527..be97525 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationSuccessHandler.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/authentication/CustomAuthenticationSuccessHandler.java @@ -1,6 +1,8 @@ package com.bpgroup.poc.admin.security.authentication; import com.bpgroup.poc.admin.app.authentication.AuthenticationResponse; +import com.bpgroup.poc.admin.common.CookieHelper; +import com.bpgroup.poc.admin.security.jwt.JwtTokenConstants; import com.bpgroup.poc.admin.security.jwt.JwtTokenGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.Cookie; @@ -12,6 +14,7 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.UUID; public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override @@ -21,8 +24,10 @@ public class CustomAuthenticationSuccessHandler implements AuthenticationSuccess response.setCharacterEncoding(StandardCharsets.UTF_8.name()); String jwtToken = JwtTokenGenerator.generate(authentication.getName()); - Cookie jwtCookie = JwtTokenGenerator.createJwtCookie(jwtToken); - response.addCookie(jwtCookie); + Cookie at = CookieHelper.createCookie(JwtTokenConstants.ACCESS_TOKEN, jwtToken); + Cookie rt = CookieHelper.createCookie(JwtTokenConstants.REFRESH_TOKEN, UUID.randomUUID().toString()); + response.addCookie(at); + response.addCookie(rt); String jsonResponse = new ObjectMapper().writeValueAsString( AuthenticationResponse.success() diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenConstants.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenConstants.java index b69578c..1cdf05e 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenConstants.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenConstants.java @@ -5,8 +5,9 @@ package com.bpgroup.poc.admin.security.jwt; */ public class JwtTokenConstants { public static final String ISSUER = "BP"; - public static final String SUBJECT = "Jwt Token"; + public static final String SUBJECT = "TOKEN"; public static final String KEY = "8530b13adb4e420d9694b27570635b47"; - public static final String NAME = "JWT-TOKEN"; + public static final String ACCESS_TOKEN = "AT"; + public static final String REFRESH_TOKEN = "RT"; public static final long EXPIRATION_TIME = 30000; } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenGenerator.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenGenerator.java index 03ede9c..1d13bea 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenGenerator.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenGenerator.java @@ -2,7 +2,6 @@ package com.bpgroup.poc.admin.security.jwt; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; -import jakarta.servlet.http.Cookie; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; @@ -20,11 +19,4 @@ public class JwtTokenGenerator { .signWith(key) .compact(); } - - public static Cookie createJwtCookie(String jwtToken) { - Cookie jwtCookie = new Cookie(JwtTokenConstants.NAME, jwtToken); - jwtCookie.setHttpOnly(true); - jwtCookie.setPath("/"); - return jwtCookie; - } } diff --git a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenValidateFilter.java b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenValidateFilter.java index e9dd2ec..55b5e8e 100644 --- a/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenValidateFilter.java +++ b/poc/admin/src/main/java/com/bpgroup/poc/admin/security/jwt/JwtTokenValidateFilter.java @@ -3,6 +3,7 @@ package com.bpgroup.poc.admin.security.jwt; import com.bpgroup.poc.admin.common.CookieHelper; import com.bpgroup.poc.admin.common.JwtHelper; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -20,9 +21,10 @@ import java.util.stream.Stream; public class JwtTokenValidateFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String sessionId = request.getSession().getId(); try { try { - Optional jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.NAME); + Optional jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.ACCESS_TOKEN); if (jwtToken.isPresent()) { Claims claims = JwtHelper.getClaims(JwtTokenConstants.KEY, jwtToken.get()); String username = claims.get("username", String.class); @@ -30,8 +32,10 @@ public class JwtTokenValidateFilter extends OncePerRequestFilter { UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null, null); SecurityContextHolder.getContext().setAuthentication(auth); } + } catch (ExpiredJwtException e) { + log.info("SESSION ID: {} Request - JWT 토큰 만료", sessionId); } catch (Exception e) { - log.error("JWT validation failed: {}", e.getMessage()); + log.error("SESSION ID: {} Request - JWT 토큰 검증 실패", sessionId); } } finally { filterChain.doFilter(request, response);