admin: at/rt 토큰 발급
This commit is contained in:
parent
d2fdb0824b
commit
bbd2bc4ded
|
|
@ -8,6 +8,14 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class CookieHelper {
|
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<String> getValueFromCookieWithName(String name) {
|
public static Optional<String> getValueFromCookieWithName(String name) {
|
||||||
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||||
HttpServletRequest request = attr.getRequest();
|
HttpServletRequest request = attr.getRequest();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.bpgroup.poc.admin.common.CookieHelper;
|
||||||
import com.bpgroup.poc.admin.common.JwtHelper;
|
import com.bpgroup.poc.admin.common.JwtHelper;
|
||||||
import com.bpgroup.poc.admin.security.jwt.JwtTokenConstants;
|
import com.bpgroup.poc.admin.security.jwt.JwtTokenConstants;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.ExpiredJwtException;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -50,7 +51,7 @@ public class LoggingFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private void loggingRequest(ContentCachingRequestWrapper request, String sessionId) {
|
private void loggingRequest(ContentCachingRequestWrapper request, String sessionId) {
|
||||||
String requestValue = new String(request.getContentAsByteArray(), StandardCharsets.UTF_8);
|
String requestValue = new String(request.getContentAsByteArray(), StandardCharsets.UTF_8);
|
||||||
Optional<String> jwtToken = CookieHelper.getValueFromCookieWithName(request, JwtTokenConstants.NAME);
|
Optional<String> jwtToken = CookieHelper.getValueFromCookieWithName(request, JwtTokenConstants.ACCESS_TOKEN);
|
||||||
|
|
||||||
if (jwtToken.isPresent()) {
|
if (jwtToken.isPresent()) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -65,19 +66,21 @@ public class LoggingFilter extends OncePerRequestFilter {
|
||||||
username
|
username
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
} catch (ExpiredJwtException e) {
|
||||||
|
log.info("SESSION ID: {} Request - JWT 토큰 만료", sessionId);
|
||||||
} catch (Exception e) {
|
} 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 - method: {} uri: {}", sessionId, request.getMethod(), request.getRequestURI());
|
||||||
log.info("session ID: {} Request - params: {}", sessionId, requestValue);
|
log.info("SESSION ID: {} Request - params: {}", sessionId, requestValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loggingResponse(ContentCachingResponseWrapper response, String sessionId) {
|
private void loggingResponse(ContentCachingResponseWrapper response, String sessionId) {
|
||||||
String contentType = response.getContentType();
|
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)) {
|
if (contentType != null && isLoggingContentType(contentType)) {
|
||||||
String responseValue = new String(response.getContentAsByteArray(), StandardCharsets.UTF_8);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package com.bpgroup.poc.admin.security;
|
package com.bpgroup.poc.admin.security;
|
||||||
|
|
||||||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationEntryPoint;
|
import com.bpgroup.poc.admin.security.authentication.*;
|
||||||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationFilter;
|
|
||||||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationProvider;
|
|
||||||
import com.bpgroup.poc.admin.app.authentication.AuthenticationService;
|
import com.bpgroup.poc.admin.app.authentication.AuthenticationService;
|
||||||
import com.bpgroup.poc.admin.security.authorization.CustomAccessDeniedHandler;
|
import com.bpgroup.poc.admin.security.authorization.CustomAccessDeniedHandler;
|
||||||
import com.bpgroup.poc.admin.security.authorization.CustomAuthorizationManager;
|
import com.bpgroup.poc.admin.security.authorization.CustomAuthorizationManager;
|
||||||
|
|
@ -81,7 +79,7 @@ public class SecurityConfig {
|
||||||
http.logout(c -> c
|
http.logout(c -> c
|
||||||
.logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_PATH, "GET"))
|
.logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_PATH, "GET"))
|
||||||
.logoutSuccessUrl(LOGIN_PATH)
|
.logoutSuccessUrl(LOGIN_PATH)
|
||||||
.deleteCookies(JwtTokenConstants.NAME)
|
.deleteCookies(JwtTokenConstants.ACCESS_TOKEN)
|
||||||
);
|
);
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
|
|
@ -103,6 +101,8 @@ public class SecurityConfig {
|
||||||
public CustomAuthenticationFilter authenticationGenerateFilter() {
|
public CustomAuthenticationFilter authenticationGenerateFilter() {
|
||||||
CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
|
CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
|
||||||
filter.setAuthenticationManager(authenticationManager());
|
filter.setAuthenticationManager(authenticationManager());
|
||||||
|
filter.setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler());
|
||||||
|
filter.setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler());
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import java.util.Optional;
|
||||||
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
@Override
|
@Override
|
||||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||||
Optional<String> jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.NAME);
|
Optional<String> jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.ACCESS_TOKEN);
|
||||||
if (jwtToken.isPresent()) {
|
if (jwtToken.isPresent()) {
|
||||||
response.sendRedirect("/login?error=" + URLEncoder.encode("로그인 세션이 만료되었습니다. 다시 로그인 해주세요.", StandardCharsets.UTF_8));
|
response.sendRedirect("/login?error=" + URLEncoder.encode("로그인 세션이 만료되었습니다. 다시 로그인 해주세요.", StandardCharsets.UTF_8));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ public class CustomAuthenticationFilter extends AbstractAuthenticationProcessing
|
||||||
|
|
||||||
public CustomAuthenticationFilter() {
|
public CustomAuthenticationFilter() {
|
||||||
super(new AntPathRequestMatcher(DEFAULT_LOGIN_REQUEST_URL, HTTP_METHOD)); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.
|
super(new AntPathRequestMatcher(DEFAULT_LOGIN_REQUEST_URL, HTTP_METHOD)); // 위에서 설정한 /oauth2/login/* 의 요청에, GET으로 온 요청을 처리하기 위해 설정한다.
|
||||||
setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler());
|
|
||||||
setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.bpgroup.poc.admin.security.authentication;
|
package com.bpgroup.poc.admin.security.authentication;
|
||||||
|
|
||||||
import com.bpgroup.poc.admin.app.authentication.AuthenticationResponse;
|
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.bpgroup.poc.admin.security.jwt.JwtTokenGenerator;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.servlet.http.Cookie;
|
import jakarta.servlet.http.Cookie;
|
||||||
|
|
@ -12,6 +14,7 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -21,8 +24,10 @@ public class CustomAuthenticationSuccessHandler implements AuthenticationSuccess
|
||||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
|
||||||
String jwtToken = JwtTokenGenerator.generate(authentication.getName());
|
String jwtToken = JwtTokenGenerator.generate(authentication.getName());
|
||||||
Cookie jwtCookie = JwtTokenGenerator.createJwtCookie(jwtToken);
|
Cookie at = CookieHelper.createCookie(JwtTokenConstants.ACCESS_TOKEN, jwtToken);
|
||||||
response.addCookie(jwtCookie);
|
Cookie rt = CookieHelper.createCookie(JwtTokenConstants.REFRESH_TOKEN, UUID.randomUUID().toString());
|
||||||
|
response.addCookie(at);
|
||||||
|
response.addCookie(rt);
|
||||||
|
|
||||||
String jsonResponse = new ObjectMapper().writeValueAsString(
|
String jsonResponse = new ObjectMapper().writeValueAsString(
|
||||||
AuthenticationResponse.success()
|
AuthenticationResponse.success()
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ package com.bpgroup.poc.admin.security.jwt;
|
||||||
*/
|
*/
|
||||||
public class JwtTokenConstants {
|
public class JwtTokenConstants {
|
||||||
public static final String ISSUER = "BP";
|
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 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;
|
public static final long EXPIRATION_TIME = 30000;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.bpgroup.poc.admin.security.jwt;
|
||||||
|
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
import jakarta.servlet.http.Cookie;
|
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
@ -20,11 +19,4 @@ public class JwtTokenGenerator {
|
||||||
.signWith(key)
|
.signWith(key)
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Cookie createJwtCookie(String jwtToken) {
|
|
||||||
Cookie jwtCookie = new Cookie(JwtTokenConstants.NAME, jwtToken);
|
|
||||||
jwtCookie.setHttpOnly(true);
|
|
||||||
jwtCookie.setPath("/");
|
|
||||||
return jwtCookie;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.bpgroup.poc.admin.security.jwt;
|
||||||
import com.bpgroup.poc.admin.common.CookieHelper;
|
import com.bpgroup.poc.admin.common.CookieHelper;
|
||||||
import com.bpgroup.poc.admin.common.JwtHelper;
|
import com.bpgroup.poc.admin.common.JwtHelper;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.ExpiredJwtException;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -20,9 +21,10 @@ import java.util.stream.Stream;
|
||||||
public class JwtTokenValidateFilter extends OncePerRequestFilter {
|
public class JwtTokenValidateFilter extends OncePerRequestFilter {
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
String sessionId = request.getSession().getId();
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
Optional<String> jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.NAME);
|
Optional<String> jwtToken = CookieHelper.getValueFromCookieWithName(JwtTokenConstants.ACCESS_TOKEN);
|
||||||
if (jwtToken.isPresent()) {
|
if (jwtToken.isPresent()) {
|
||||||
Claims claims = JwtHelper.getClaims(JwtTokenConstants.KEY, jwtToken.get());
|
Claims claims = JwtHelper.getClaims(JwtTokenConstants.KEY, jwtToken.get());
|
||||||
String username = claims.get("username", String.class);
|
String username = claims.get("username", String.class);
|
||||||
|
|
@ -30,8 +32,10 @@ public class JwtTokenValidateFilter extends OncePerRequestFilter {
|
||||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null, null);
|
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null, null);
|
||||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
}
|
}
|
||||||
|
} catch (ExpiredJwtException e) {
|
||||||
|
log.info("SESSION ID: {} Request - JWT 토큰 만료", sessionId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("JWT validation failed: {}", e.getMessage());
|
log.error("SESSION ID: {} Request - JWT 토큰 검증 실패", sessionId);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue