

250423 김혜민 세션로그인 오류 수정
@404bc5ff8abcea6066e2face5f3ed66c9f1ff857
--- build.gradle
+++ build.gradle
... | ... | @@ -3,29 +3,38 @@ |
3 | 3 |
*/ |
4 | 4 |
|
5 | 5 |
plugins { |
6 |
-// id 'java-library' |
|
7 |
-// id 'maven-publish' |
|
8 | 6 |
id 'java' |
9 | 7 |
id 'org.springframework.boot' version '3.4.1' |
10 | 8 |
id 'io.spring.dependency-management' version '1.1.7' |
11 | 9 |
} |
12 | 10 |
|
11 |
+ |
|
12 |
+group = 'com.takensoft' |
|
13 |
+version = '0.0.1-SNAPSHOT' |
|
14 |
+ |
|
15 |
+java { |
|
16 |
+ toolchain { |
|
17 |
+ languageVersion = JavaLanguageVersion.of(17) |
|
18 |
+ } |
|
19 |
+} |
|
20 |
+ |
|
21 |
+configurations { |
|
22 |
+ compileOnly { |
|
23 |
+ extendsFrom annotationProcessor |
|
24 |
+ } |
|
25 |
+} |
|
26 |
+ |
|
27 |
+ |
|
13 | 28 |
repositories { |
14 |
-// mavenLocal() |
|
15 | 29 |
mavenCentral() |
16 | 30 |
maven { |
17 |
- url = uri('https://repo1.maven.org/maven2/') |
|
31 |
+ url "https://repo1.maven.org/maven2/" |
|
18 | 32 |
} |
19 |
- |
|
20 | 33 |
maven { |
21 |
- url = uri('https://maven.egovframe.go.kr/maven/') |
|
34 |
+ url "https://maven.egovframe.go.kr/maven/" |
|
22 | 35 |
mavenContent { |
23 | 36 |
releasesOnly() |
24 | 37 |
} |
25 |
- } |
|
26 |
- |
|
27 |
- maven { |
|
28 |
- url = uri('https://repo.maven.apache.org/maven2/') |
|
29 | 38 |
} |
30 | 39 |
} |
31 | 40 |
|
... | ... | @@ -77,13 +86,9 @@ |
77 | 86 |
testImplementation 'org.springframework.security:spring-security-test' |
78 | 87 |
} |
79 | 88 |
|
80 |
-group = 'com.takensoft' |
|
81 |
-// version = '1.0.0' |
|
82 |
-version = '0.0.1-SNAPSHOT' |
|
83 |
-//description = 'cms' |
|
84 | 89 |
|
85 | 90 |
// java.sourceCompatibility = JavaVersion.VERSION_1_8 |
86 |
-java.sourceCompatibility = '17' |
|
91 |
+//java.sourceCompatibility = '17' |
|
87 | 92 |
/*publishing { |
88 | 93 |
publications { |
89 | 94 |
maven(MavenPublication) { |
--- src/main/java/com/takensoft/cms/loginPolicy/web/LoginPolicyController.java
+++ src/main/java/com/takensoft/cms/loginPolicy/web/LoginPolicyController.java
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 |
import com.takensoft.cms.loginPolicy.service.LoginPolicyService; |
5 | 5 |
import com.takensoft.cms.loginPolicy.vo.LoginModeVO; |
6 | 6 |
import com.takensoft.cms.loginPolicy.vo.LoginPolicyVO; |
7 |
+import com.takensoft.cms.mber.vo.MberVO; |
|
7 | 8 |
import com.takensoft.cms.token.service.RefreshTokenService; |
8 | 9 |
import com.takensoft.common.message.MessageCode; |
9 | 10 |
import com.takensoft.common.util.JWTUtil; |
... | ... | @@ -15,6 +16,8 @@ |
15 | 16 |
import org.springframework.dao.DuplicateKeyException; |
16 | 17 |
import org.springframework.data.redis.core.RedisTemplate; |
17 | 18 |
import org.springframework.http.ResponseEntity; |
19 |
+import org.springframework.security.core.Authentication; |
|
20 |
+import org.springframework.security.core.context.SecurityContextHolder; |
|
18 | 21 |
import org.springframework.web.bind.annotation.*; |
19 | 22 |
|
20 | 23 |
import java.util.Set; |
... | ... | @@ -65,7 +68,22 @@ |
65 | 68 |
public ResponseEntity<?> saveLoginPolicy(@RequestBody LoginPolicyVO loginPolicyVO, HttpServletRequest request) { |
66 | 69 |
try { |
67 | 70 |
String token = request.getHeader("Authorization"); |
68 |
- String mbrId = (String) jwtUtil.getClaim(token, "mbrId"); |
|
71 |
+ |
|
72 |
+ String loginMode = loginModeService.getLoginMode(); |
|
73 |
+ String mbrId = null; |
|
74 |
+ |
|
75 |
+ if ("J".equals(loginMode)) { |
|
76 |
+ if (token == null || token.isBlank()) { |
|
77 |
+ return resUtil.errorRes(MessageCode.COMMON_BAD_REQUEST); // JWT인데 토큰 없음 |
|
78 |
+ } |
|
79 |
+ mbrId = (String) jwtUtil.getClaim(token, "mbrId"); |
|
80 |
+ } else { |
|
81 |
+ |
|
82 |
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication(); |
|
83 |
+ if (auth != null && auth.getPrincipal() instanceof MberVO) { |
|
84 |
+ mbrId = ((MberVO) auth.getPrincipal()).getMbrId(); |
|
85 |
+ } |
|
86 |
+ } |
|
69 | 87 |
|
70 | 88 |
if (mbrId == null || mbrId.isBlank()) { |
71 | 89 |
return resUtil.errorRes(MessageCode.COMMON_BAD_REQUEST); |
... | ... | @@ -74,11 +92,10 @@ |
74 | 92 |
loginPolicyVO.setRgtr(mbrId); |
75 | 93 |
|
76 | 94 |
int result = loginPolicyService.insertPolicy(loginPolicyVO); |
77 |
- |
|
78 | 95 |
if (result > 0) { |
79 | 96 |
return resUtil.successRes(result, MessageCode.COMMON_SUCCESS); |
80 | 97 |
} else { |
81 |
- return resUtil.errorRes(MessageCode.COMMON_INSERT_FAIL); // 저장 실패 |
|
98 |
+ return resUtil.errorRes(MessageCode.COMMON_INSERT_FAIL); |
|
82 | 99 |
} |
83 | 100 |
|
84 | 101 |
} catch (DuplicateKeyException e) { |
... | ... | @@ -96,8 +113,7 @@ |
96 | 113 |
*/ |
97 | 114 |
@PostMapping(value ="/getLoginMode.json") |
98 | 115 |
public Object getLoginMode() { |
99 |
- // String loginMode = loginModeService.getLoginMode(); |
|
100 |
- String loginMode = "S"; |
|
116 |
+ String loginMode = loginModeService.getLoginMode(); |
|
101 | 117 |
return resUtil.successRes(loginMode, MessageCode.COMMON_SUCCESS); |
102 | 118 |
} |
103 | 119 |
|
--- src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
+++ src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
... | ... | @@ -73,6 +73,11 @@ |
73 | 73 |
HttpSession session = req.getSession(false); |
74 | 74 |
if (session != null) session.invalidate(); |
75 | 75 |
sessionUtil.removeSession(mbrId); |
76 |
+ |
|
77 |
+ Cookie cookie = new Cookie("JSESSIONID", null); |
|
78 |
+ cookie.setMaxAge(0); // 삭제 |
|
79 |
+ cookie.setPath("/"); |
|
80 |
+ res.addCookie(cookie); |
|
76 | 81 |
} else { |
77 | 82 |
// JWT 방식: Redis에서 삭제 |
78 | 83 |
if (!loginPolicyService.getPolicy()) { |
--- src/main/java/com/takensoft/common/config/SecurityConfig.java
+++ src/main/java/com/takensoft/common/config/SecurityConfig.java
... | ... | @@ -173,12 +173,7 @@ |
173 | 173 |
// .anyRequest().permitAll() // 모든 사용자 접근 가능 |
174 | 174 |
); |
175 | 175 |
|
176 |
- // 로그인 방식에 따라 필터 적용 (JWT or 세션) |
|
177 |
- if (loginModeService.getLoginMode().equals("S")) { |
|
178 |
- http.addFilterBefore(new SessionAuthFilter(jwtUtil, redisTemplate, loginPolicyService, refreshTokenService), LoginFilter.class); |
|
179 |
- } else { |
|
180 |
- http.addFilterBefore(new JWTFilter(jwtUtil, appConfig, loginPolicyService, redisTemplate), LoginFilter.class); |
|
181 |
- } |
|
176 |
+ http.addFilterBefore(new JWTFilter(jwtUtil, appConfig, loginModeService, loginPolicyService, redisTemplate), LoginFilter.class); |
|
182 | 177 |
|
183 | 178 |
http.addFilterBefore(new AccesFilter(accesCtrlService, httpRequestUtil, appConfig), JWTFilter.class); // 아이피 검증 |
184 | 179 |
http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService, lgnHstryService, httpRequestUtil, |
--- src/main/java/com/takensoft/common/filter/JWTFilter.java
+++ src/main/java/com/takensoft/common/filter/JWTFilter.java
... | ... | @@ -1,5 +1,6 @@ |
1 | 1 |
package com.takensoft.common.filter; |
2 | 2 |
|
3 |
+import com.takensoft.cms.loginPolicy.service.LoginModeService; |
|
3 | 4 |
import com.takensoft.cms.loginPolicy.service.LoginPolicyService; |
4 | 5 |
import com.takensoft.cms.mber.vo.MberAuthorVO; |
5 | 6 |
import com.takensoft.cms.mber.vo.MberVO; |
... | ... | @@ -9,6 +10,7 @@ |
9 | 10 |
import com.takensoft.common.util.JWTUtil; |
10 | 11 |
import io.jsonwebtoken.ExpiredJwtException; |
11 | 12 |
import io.jsonwebtoken.JwtException; |
13 |
+import jakarta.servlet.http.HttpSession; |
|
12 | 14 |
import org.springframework.data.redis.core.RedisTemplate; |
13 | 15 |
import org.springframework.http.HttpStatus; |
14 | 16 |
import org.springframework.http.MediaType; |
... | ... | @@ -39,18 +41,22 @@ |
39 | 41 |
public class JWTFilter extends OncePerRequestFilter { |
40 | 42 |
|
41 | 43 |
private static final String AUTHORIZATION_HEADER = "Authorization"; |
44 |
+ private static final String SESSION_JWT_KEY = "JWT_TOKEN"; |
|
42 | 45 |
private final JWTUtil jwtUtil; |
43 | 46 |
private final AppConfig appConfig; |
44 | 47 |
private final LoginPolicyService loginPolicyService; |
45 | 48 |
private final RedisTemplate<String, String> redisTemplate; |
49 |
+ private final LoginModeService loginModeService; |
|
50 |
+ |
|
46 | 51 |
/** |
47 | 52 |
* @param jwtUtil JWT 유틸리티 클래스의 인스턴스 |
48 | 53 |
* |
49 | 54 |
* JWTFilter 생성자 |
50 | 55 |
*/ |
51 |
- public JWTFilter(JWTUtil jwtUtil, AppConfig appConfig, LoginPolicyService loginPolicyService, RedisTemplate<String, String> redisTemplate) { |
|
56 |
+ public JWTFilter(JWTUtil jwtUtil, AppConfig appConfig, LoginModeService loginModeService, LoginPolicyService loginPolicyService, RedisTemplate<String, String> redisTemplate) { |
|
52 | 57 |
this.jwtUtil = jwtUtil; |
53 | 58 |
this.appConfig = appConfig; |
59 |
+ this.loginModeService = loginModeService; |
|
54 | 60 |
this.loginPolicyService = loginPolicyService; |
55 | 61 |
this.redisTemplate = redisTemplate; |
56 | 62 |
} |
... | ... | @@ -66,66 +72,33 @@ |
66 | 72 |
@Override |
67 | 73 |
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
68 | 74 |
try { |
69 |
- // 헤더에서 access에 대한 토큰을 꺼냄 |
|
70 |
- String accessToken = request.getHeader(AUTHORIZATION_HEADER); |
|
71 |
- // 토큰이 없다면 다음 필터로 넘김 |
|
72 |
- if(accessToken == null) { |
|
75 |
+ String loginMode = loginModeService.getLoginMode(); |
|
76 |
+ String accessToken = resolveToken(request, loginMode); |
|
77 |
+ |
|
78 |
+ if (accessToken == null) { |
|
73 | 79 |
filterChain.doFilter(request, response); |
74 | 80 |
return; |
75 | 81 |
} |
76 | 82 |
|
77 |
- // 토큰 만료 여부 검증 |
|
78 | 83 |
if ((Boolean) jwtUtil.getClaim(accessToken, "isExpired")) { |
79 |
- response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
|
80 |
- response.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
81 |
- |
|
82 |
- ErrorResponse errorResponse = new ErrorResponse(); |
|
83 |
- errorResponse.setMessage("Token expired"); |
|
84 |
- errorResponse.setPath(request.getRequestURI()); |
|
85 |
- errorResponse.setError(HttpStatus.UNAUTHORIZED.getReasonPhrase()); |
|
86 |
- errorResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
87 |
- errorResponse.setTimestamp(LocalDateTime.now()); |
|
88 |
- |
|
89 |
- response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse)); |
|
84 |
+ sendTokenExpiredResponse(response, request); |
|
90 | 85 |
return; |
91 | 86 |
} |
92 |
- // 토큰에서 페이로드 확인[ 발급시 명시 ] |
|
93 |
- String category = (String) jwtUtil.getClaim(accessToken, "category"); |
|
94 |
- |
|
95 | 87 |
|
96 | 88 |
MberVO mber = new MberVO( |
97 |
- (String) jwtUtil.getClaim(accessToken, "mbrId") |
|
98 |
- , (String) jwtUtil.getClaim(accessToken, "lgnId") |
|
99 |
- , (List<MberAuthorVO>) jwtUtil.getClaim(accessToken, "roles") |
|
89 |
+ (String) jwtUtil.getClaim(accessToken, "mbrId"), |
|
90 |
+ (String) jwtUtil.getClaim(accessToken, "lgnId"), |
|
91 |
+ (List<MberAuthorVO>) jwtUtil.getClaim(accessToken, "roles") |
|
100 | 92 |
); |
101 | 93 |
|
102 |
- // 중복 로그인 비허용 설정이면 Redis에서 최신 JWT 가져와 비교 |
|
103 |
- String userId = (String) jwtUtil.getClaim(accessToken, "mbrId"); |
|
104 |
- if (!loginPolicyService.getPolicy()) { |
|
105 |
- String storedToken = redisTemplate.opsForValue().get("jwt:" + userId); |
|
106 |
- if (storedToken == null) { |
|
107 |
- } else if (!storedToken.equals(accessToken)) { |
|
108 |
- |
|
109 |
- response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
|
110 |
- response.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
111 |
- |
|
112 |
- ErrorResponse errorResponse = new ErrorResponse(); |
|
113 |
- errorResponse.setMessage("Token expired"); |
|
114 |
- errorResponse.setPath(request.getRequestURI()); |
|
115 |
- errorResponse.setError(HttpStatus.UNAUTHORIZED.getReasonPhrase()); |
|
116 |
- errorResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
117 |
- errorResponse.setTimestamp(LocalDateTime.now()); |
|
118 |
- // 응답 헤더 설정 및 json 응답 전송 |
|
119 |
- response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
|
120 |
- response.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
121 |
- response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse)); |
|
122 |
- return; |
|
123 |
- } |
|
94 |
+ if (!loginPolicyService.getPolicy() && !isTokenValid(mber.getMbrId(), accessToken)) { |
|
95 |
+ sendTokenExpiredResponse(response, request); |
|
96 |
+ return; |
|
124 | 97 |
} |
125 |
- // 시큐리티 컨텍스트에 사용자 정보 설정 |
|
98 |
+ |
|
126 | 99 |
Authentication authToken = new UsernamePasswordAuthenticationToken(mber, null, mber.getAuthorities()); |
127 | 100 |
SecurityContextHolder.getContext().setAuthentication(authToken); |
128 |
- // 다음 필터로 이동 |
|
101 |
+ |
|
129 | 102 |
filterChain.doFilter(request, response); |
130 | 103 |
} catch (ExpiredJwtException e) { |
131 | 104 |
FilterExceptionHandler.jwtError(response, e); |
... | ... | @@ -137,4 +110,32 @@ |
137 | 110 |
FilterExceptionHandler.jwtError(response, e); |
138 | 111 |
} |
139 | 112 |
} |
113 |
+ |
|
114 |
+ private String resolveToken(HttpServletRequest request, String loginMode) { |
|
115 |
+ if ("S".equals(loginMode)) { |
|
116 |
+ HttpSession session = request.getSession(false); |
|
117 |
+ return session != null ? (String) session.getAttribute(SESSION_JWT_KEY) : null; |
|
118 |
+ } else { |
|
119 |
+ return request.getHeader(AUTHORIZATION_HEADER); |
|
120 |
+ } |
|
121 |
+ } |
|
122 |
+ |
|
123 |
+ private boolean isTokenValid(String mbrId, String accessToken) { |
|
124 |
+ String storedToken = redisTemplate.opsForValue().get("jwt:" + mbrId); |
|
125 |
+ return storedToken == null || storedToken.equals(accessToken); |
|
126 |
+ } |
|
127 |
+ |
|
128 |
+ |
|
129 |
+ private void sendTokenExpiredResponse(HttpServletResponse response, HttpServletRequest request) throws IOException { |
|
130 |
+ ErrorResponse errorResponse = new ErrorResponse(); |
|
131 |
+ errorResponse.setMessage("Token expired"); |
|
132 |
+ errorResponse.setPath(request.getRequestURI()); |
|
133 |
+ errorResponse.setError(HttpStatus.UNAUTHORIZED.getReasonPhrase()); |
|
134 |
+ errorResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
135 |
+ errorResponse.setTimestamp(LocalDateTime.now()); |
|
136 |
+ |
|
137 |
+ response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
|
138 |
+ response.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|
139 |
+ response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse)); |
|
140 |
+ } |
|
140 | 141 |
}(파일 끝에 줄바꿈 문자 없음) |
--- src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
... | ... | @@ -1,120 +0,0 @@ |
1 | -package com.takensoft.common.filter; | |
2 | - | |
3 | -import com.takensoft.cms.loginPolicy.service.LoginPolicyService; | |
4 | -import com.takensoft.cms.mber.vo.MberAuthorVO; | |
5 | -import com.takensoft.cms.mber.vo.MberVO; | |
6 | -import com.takensoft.cms.token.service.RefreshTokenService; | |
7 | -import com.takensoft.common.util.JWTUtil; | |
8 | -import jakarta.servlet.FilterChain; | |
9 | -import jakarta.servlet.ServletException; | |
10 | -import jakarta.servlet.http.HttpServletRequest; | |
11 | -import jakarta.servlet.http.HttpServletResponse; | |
12 | -import jakarta.servlet.http.HttpSession; | |
13 | -import org.springframework.beans.factory.annotation.Value; | |
14 | -import org.springframework.data.redis.core.RedisTemplate; | |
15 | -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | |
16 | -import org.springframework.security.core.context.SecurityContextHolder; | |
17 | -import org.springframework.web.filter.OncePerRequestFilter; | |
18 | - | |
19 | -import java.io.IOException; | |
20 | -import java.util.List; | |
21 | - | |
22 | -/** | |
23 | - * @author takensoft | |
24 | - * @since 2024.03.20 | |
25 | - * @modification | |
26 | - * since | author | description | |
27 | - * 2024.03.20 | takensoft | 최초 등록 | |
28 | - * | |
29 | - * OncePerRequestFilter - 한 번의 요청마다 단 한 번만 필터링 작업을 수행하는 필터를 제공하는 클래스 | |
30 | - * | |
31 | - * 세션 검증 Filter | |
32 | - */ | |
33 | -public class SessionAuthFilter extends OncePerRequestFilter { | |
34 | - | |
35 | - private final JWTUtil jwtUtil; | |
36 | - private final RedisTemplate<String, String> redisTemplate; | |
37 | - private final LoginPolicyService loginPolicyService; | |
38 | - private final RefreshTokenService refreshTokenService; | |
39 | - | |
40 | - @Value("${jwt.accessTime}") | |
41 | - private long JWT_ACCESSTIME; | |
42 | - public SessionAuthFilter(JWTUtil jwtUtil, RedisTemplate<String, String> redisTemplate, LoginPolicyService loginPolicyService, RefreshTokenService refreshTokenService) { | |
43 | - this.jwtUtil = jwtUtil; | |
44 | - this.redisTemplate = redisTemplate; | |
45 | - this.loginPolicyService = loginPolicyService; | |
46 | - this.refreshTokenService = refreshTokenService; | |
47 | - } | |
48 | - /** | |
49 | - * @param request HttpServletRequest 객체 | |
50 | - * @param response HttpServletResponse 객체 | |
51 | - * @param filterChain 필터 체인을 통해 다음 필터로 요청을 전달 | |
52 | - * @throws ServletException 필터 처리 중 발생한 서블릿 예외 | |
53 | - * @throws IOException 필터 처리 중 발생한 IO 예외 | |
54 | - * | |
55 | - * 세션 Filter 검증 | |
56 | - */ | |
57 | - @Override | |
58 | - protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { | |
59 | - HttpSession session = request.getSession(false); | |
60 | - | |
61 | - // 세션이 없거나 JWT 토큰이 없으면 인증 실패 처리 | |
62 | - if (session == null || session.getAttribute("JWT_TOKEN") == null) { | |
63 | - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); | |
64 | - return; | |
65 | - } | |
66 | - | |
67 | - // 세션에서 JWT 토큰 가져오기 | |
68 | - String accessToken = (String) session.getAttribute("JWT_TOKEN"); | |
69 | - | |
70 | - // 만료 여부 검증 | |
71 | - if ((Boolean) jwtUtil.getClaim(accessToken, "isExpired")) { | |
72 | - // 만료된 경우, refresh 토큰 검사 | |
73 | - String refreshToken = refreshTokenService.getRefreshTokenFromCookie(request); | |
74 | - | |
75 | - if (refreshToken == null || (Boolean) jwtUtil.getClaim(refreshToken, "isExpired")) { | |
76 | - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token expired"); | |
77 | - return; | |
78 | - } | |
79 | - | |
80 | - // Refresh 토큰이 유효하다면 새로운 Access 토큰 발급 | |
81 | - try { | |
82 | - String newAccessToken = jwtUtil.createJwt( | |
83 | - "Authorization", | |
84 | - (String) jwtUtil.getClaim(refreshToken, "mbrId"), | |
85 | - (String) jwtUtil.getClaim(refreshToken, "lgnId"), | |
86 | - (String) jwtUtil.getClaim(refreshToken, "mbrNm"), | |
87 | - (List) jwtUtil.getClaim(refreshToken, "roles"), | |
88 | - JWT_ACCESSTIME); | |
89 | - session.setAttribute("JWT_TOKEN", newAccessToken); | |
90 | - accessToken = newAccessToken; | |
91 | - } catch (Exception e) { | |
92 | - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Failed to refresh token"); | |
93 | - return; | |
94 | - } | |
95 | - } | |
96 | - | |
97 | - // 중복 로그인 여부 확인 (JWT 방식과 동일하게 Redis 체크) | |
98 | - if (!loginPolicyService.getPolicy()) { | |
99 | - String mbrId = (String) jwtUtil.getClaim(accessToken, "mbrId"); | |
100 | - String storedToken = redisTemplate.opsForValue().get("jwt:" + mbrId); | |
101 | - if (storedToken != null && !storedToken.equals(accessToken)) { | |
102 | - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "다른 기기에서 로그인되었습니다."); | |
103 | - return; | |
104 | - } | |
105 | - } | |
106 | - | |
107 | - // 사용자 인증 정보 SecurityContext에 저장 | |
108 | - MberVO mber = new MberVO(); | |
109 | - List<MberAuthorVO> roles = (List<MberAuthorVO>) jwtUtil.getClaim(accessToken, "roles"); | |
110 | - mber.setLgnId((String) jwtUtil.getClaim(accessToken, "lgnId")); | |
111 | - mber.setMbrId((String) jwtUtil.getClaim(accessToken, "mbrId")); | |
112 | - mber.setMbrNm((String) jwtUtil.getClaim(accessToken, "mbrNm")); | |
113 | - mber.setAuthorList(roles); | |
114 | - | |
115 | - UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(mber, null, mber.getAuthorities()); | |
116 | - SecurityContextHolder.getContext().setAuthentication(authToken); | |
117 | - | |
118 | - filterChain.doFilter(request, response); | |
119 | - } | |
120 | -}(파일 끝에 줄바꿈 문자 없음) |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?