hmkim 03-26
250326 김혜민 중복로그인 및 세션방식 수정
@6ca0c3fb7bbf3196e04f78b2b8bccfe18bc27ce7
src/main/java/com/takensoft/cms/token/service/impl/RefreshTokenServiceImpl.java
--- src/main/java/com/takensoft/cms/token/service/impl/RefreshTokenServiceImpl.java
+++ src/main/java/com/takensoft/cms/token/service/impl/RefreshTokenServiceImpl.java
@@ -1,14 +1,13 @@
 package com.takensoft.cms.token.service.impl;
 
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
 import com.takensoft.cms.token.dao.RefreshTokenDAO;
 import com.takensoft.cms.token.service.RefreshTokenService;
 import com.takensoft.cms.mber.vo.MberAuthorVO;
 import com.takensoft.cms.mber.vo.MberVO;
 import com.takensoft.cms.token.vo.RefreshTknVO;
-import com.takensoft.common.config.RedisConfig;
 import com.takensoft.common.util.HttpRequestUtil;
 import com.takensoft.common.util.JWTUtil;
-import com.takensoft.common.util.LoginUtil;
 import io.jsonwebtoken.ExpiredJwtException;
 import lombok.RequiredArgsConstructor;
 import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
@@ -48,7 +47,7 @@
     private final RefreshTokenDAO refreshTokenDAO;
     private final JWTUtil jwtUtil;
     private final HttpRequestUtil httpRequestUtil;
-    private final LoginUtil loginUtil;
+    private final LoginPolicyService loginPolicyService;
     private final RedisTemplate<String, String> redisTemplate;
 
     @Value("${jwt.accessTime}")
@@ -149,7 +148,7 @@
             refreshTknVO.setMbrId((String) jwtUtil.getClaim(refreshTokenCheck(req).get("refreshToken").toString(), "mbrId"));
 
             //중복로그인 비허용시 삭제
-            if (!loginUtil.isAllowMultipleLogin()) {
+            if (!loginPolicyService.getPolicy()) {
                 redisTemplate.delete("jwt:" + refreshTknVO.getMbrId()); // 기존 JWT 삭제
             }
             return delete(req, refreshTknVO);
@@ -180,7 +179,7 @@
             String userId = (String) jwtUtil.getClaim(refreshToken, "mbrId");
 
             // 중복 로그인 비허용 체크 (DB에 저장된 리프레시 토큰과 비교)
-            if (!loginUtil.isAllowMultipleLogin()) {
+            if (!loginPolicyService.getPolicy()) {
                 String storedRefreshToken = redisTemplate.opsForValue().get("jwt:" + userId);
 
                 if (storedRefreshToken == null || !storedRefreshToken.equals(refreshToken)) {
@@ -239,7 +238,7 @@
     public int delete(HttpServletRequest req, RefreshTknVO refreshTknVO) {
             refreshTknVO.setUseIp(httpRequestUtil.getIp(req));
             //중복로그인 비허용시 삭제
-            if (!loginUtil.isAllowMultipleLogin()) {
+            if (!loginPolicyService.getPolicy()) {
                 redisTemplate.delete("jwt:" + refreshTknVO.getMbrId()); // 기존 JWT 삭제
             }
             return refreshTokenDAO.deleteByRefresh(refreshTknVO);
src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
--- src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
+++ src/main/java/com/takensoft/cms/token/web/RefreshTokenController.java
@@ -1,16 +1,25 @@
 package com.takensoft.cms.token.web;
 
 
+import com.takensoft.cms.loginPolicy.service.LoginModeService;
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
+import com.takensoft.cms.mber.vo.MberVO;
 import com.takensoft.cms.token.service.RefreshTokenService;
+import com.takensoft.cms.token.vo.RefreshTknVO;
 import com.takensoft.common.message.MessageCode;
 import com.takensoft.common.util.ResponseData;
 import com.takensoft.common.util.ResponseUtil;
+import com.takensoft.common.util.SessionUtil;
+import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -34,7 +43,10 @@
 
     private final ResponseUtil resUtil;
     private final RefreshTokenService refreshTokenService;
-
+    private final LoginPolicyService loginPolicyService;
+    private final LoginModeService loginModeService;
+    private final SessionUtil sessionUtil;
+    private final RedisTemplate<String, String> redisTemplate;
     /**
      * @param req - HTTP 요청 객체
      * @param res - HTTP 응답 객체
@@ -44,18 +56,41 @@
      */
     @PostMapping(value = "/mbr/logout.json")
     public ResponseEntity<?> logout(HttpServletRequest req, HttpServletResponse res){
-        int result = refreshTokenService.deleteByRefresh(req, res);
-        if(result > 0) {
-            Cookie cookie = new Cookie("refresh", null);
-            cookie.setMaxAge(0); // 생명주기
-            //cookie.setSecure(true); // https 통신을 할 경우 true로 사용
-            cookie.setPath("/"); // 쿠키 적용 범위
-            cookie.setHttpOnly(true);
-            res.addCookie(cookie);
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+        if (auth != null && auth.getPrincipal() instanceof MberVO) {
+            MberVO mber = (MberVO) auth.getPrincipal();
+            String mbrId = mber.getMbrId();
+            String loginType = loginModeService.getLoginMode(); // "J" or "S"
+
+            // ✅ Refresh 토큰 삭제 (DB)
+            RefreshTknVO refresh = new RefreshTknVO();
+            refresh.setMbrId(mbrId);
+            int result =  refreshTokenService.delete(req, refresh);
+
+            if ("S".equals(loginType)) {
+                // ✅ 세션 방식: 세션 만료 + SessionMap에서 제거
+                HttpSession session = req.getSession(false);
+                if (session != null) session.invalidate();
+                sessionUtil.removeSession(mbrId);
+            } else {
+                // ✅ JWT 방식: Redis에서 삭제
+                if (!loginPolicyService.getPolicy()) {
+                    redisTemplate.delete("jwt:" + mbrId);
+                }
+                // 쿠키 제거
+                Cookie cookie = new Cookie("refresh", null);
+                cookie.setMaxAge(0);
+                cookie.setHttpOnly(true);
+                cookie.setPath("/");
+                res.addCookie(cookie);
+            }
+
+            //  SecurityContext 제거
+            SecurityContextHolder.clearContext();
             return resUtil.successRes(result, MessageCode.LOGOUT_SUCCESS);
-        } else {
-            return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
         }
+            return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
     }
 
     /**
src/main/java/com/takensoft/common/config/SecurityConfig.java
--- src/main/java/com/takensoft/common/config/SecurityConfig.java
+++ src/main/java/com/takensoft/common/config/SecurityConfig.java
@@ -1,6 +1,8 @@
 package com.takensoft.common.config;
 
 import com.takensoft.cms.accesCtrl.service.AccesCtrlService;
+import com.takensoft.cms.loginPolicy.service.LoginModeService;
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
 import com.takensoft.cms.mber.service.LgnHstryService;
 import com.takensoft.cms.token.service.RefreshTokenService;
 import com.takensoft.common.filter.AccesFilter;
@@ -11,7 +13,7 @@
 import com.takensoft.common.exception.CustomAccessDenieHandler;
 import com.takensoft.common.exception.CustomAuthenticationEntryPoint;
 import com.takensoft.common.util.JWTUtil;
-import com.takensoft.common.util.LoginUtil;
+import com.takensoft.common.util.SessionUtil;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -53,8 +55,9 @@
     private final CustomAccessDenieHandler accessDenieHandler;
     private final HttpRequestUtil httpRequestUtil;
     private final AppConfig appConfig;
-    private final RedisConfig redisConfig;
-    private final LoginUtil loginUtil;
+    private final LoginModeService loginModeService;
+    private final LoginPolicyService loginPolicyService;
+    private final SessionUtil sessionUtil;
 
     private static String FRONT_URL;    // 프론트 접근 허용 URL
     private static long JWT_ACCESSTIME; // access 토큰 유지 시간
@@ -68,7 +71,6 @@
      * @param jwtUtil - JWT 유틸리티 객체
      * @param authenticationEntryPoint - 인증 실패 시 처리 엔트리 포인트
      * @param accessDenieHandler - 접근 거부 처리 핸들러
-     * @param loginUtil
      * @param fUrl - 프론트엔드 URL (application.yml에서 값을 읽어 옴)
      * @param aTime - JWT 접근 토큰 유효 시간 (application.yml에서 값을 읽어 옴)
      * @param rTime - JWT 리프레시 토큰 유효 시간 (application.yml에서 값을 읽어 옴)
@@ -76,9 +78,9 @@
      * @param redisTemplate
 *
      */
-    public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, AccesCtrlService accesCtrlService, AppConfig appConfig, RedisConfig redisConfig,
+    public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, AccesCtrlService accesCtrlService, AppConfig appConfig,
                           LgnHstryService lgnHstryService, CustomAuthenticationEntryPoint authenticationEntryPoint, CustomAccessDenieHandler accessDenieHandler, HttpRequestUtil httpRequestUtil,
-                          LoginUtil loginUtil, @Value("${front.url}") String fUrl, @Value("${jwt.accessTime}") long aTime, @Value("${jwt.refreshTime}") long rTime, @Value("${cookie.time}") int ctime, RedisTemplate<String, String> redisTemplate) {
+                          LoginModeService loginModeService, LoginPolicyService loginPolicyService, SessionUtil sessionUtil, @Value("${front.url}") String fUrl, @Value("${jwt.accessTime}") long aTime, @Value("${jwt.refreshTime}") long rTime, @Value("${cookie.time}") int ctime, RedisTemplate<String, String> redisTemplate) {
 
         this.authenticationConfiguration = authenticationConfiguration;
         this.refreshTokenService = refreshTokenService;
@@ -89,9 +91,9 @@
         this.jwtUtil = jwtUtil;
         this.httpRequestUtil = httpRequestUtil;
         this.appConfig = appConfig;
-        this.redisConfig = redisConfig;
-        this.loginUtil = loginUtil;
-
+        this.loginModeService = loginModeService;
+        this.loginPolicyService = loginPolicyService;
+        this.sessionUtil = sessionUtil;
         this.FRONT_URL = fUrl;
         this.JWT_ACCESSTIME = aTime;
         this.JWT_REFRESHTIME = rTime;
@@ -167,17 +169,16 @@
 //                .anyRequest().permitAll() // 모든 사용자 접근 가능
         );
 
-        // 로그인 방식에 따라 필터 적용 (JWT vs 세션)
-        if ("S".equals(loginUtil.getLoginMode())) {
-            http.addFilterBefore(new SessionAuthFilter(jwtUtil, redisTemplate, redisConfig, loginUtil), LoginFilter.class);
+        // 로그인 방식에 따라 필터 적용 (JWT or 세션)
+        if ("S".equals(loginModeService.getLoginMode())) {
+            http.addFilterBefore(new SessionAuthFilter(jwtUtil, redisTemplate, loginPolicyService), LoginFilter.class);
         } else {
-            http.addFilterBefore(new JWTFilter(jwtUtil, appConfig, loginUtil, redisTemplate), LoginFilter.class);
+            http.addFilterBefore(new JWTFilter(jwtUtil, appConfig, loginPolicyService, redisTemplate), LoginFilter.class);
         }
 
-//        http.addFilterBefore(new JWTFilter(jwtUtil, appConfig, redisConfig, redisTemplate), LoginFilter.class); // 토큰 검증 필터
         http.addFilterBefore(new AccesFilter(accesCtrlService, httpRequestUtil, appConfig), JWTFilter.class); // 아이피 검증
         http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService, lgnHstryService, httpRequestUtil,
-                appConfig,loginUtil, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME, redisTemplate), UsernamePasswordAuthenticationFilter.class); // 로그인 필터
+                 loginModeService, loginPolicyService, sessionUtil, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME, redisTemplate), UsernamePasswordAuthenticationFilter.class); // 로그인 필터
 
         return http.build();
     }
src/main/java/com/takensoft/common/filter/JWTFilter.java
--- src/main/java/com/takensoft/common/filter/JWTFilter.java
+++ src/main/java/com/takensoft/common/filter/JWTFilter.java
@@ -1,13 +1,12 @@
 package com.takensoft.common.filter;
 
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
 import com.takensoft.cms.mber.vo.MberAuthorVO;
 import com.takensoft.cms.mber.vo.MberVO;
 import com.takensoft.common.config.AppConfig;
-import com.takensoft.common.config.RedisConfig;
 import com.takensoft.common.exception.FilterExceptionHandler;
 import com.takensoft.common.util.ErrorResponse;
 import com.takensoft.common.util.JWTUtil;
-import com.takensoft.common.util.LoginUtil;
 import io.jsonwebtoken.ExpiredJwtException;
 import io.jsonwebtoken.JwtException;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -42,17 +41,17 @@
     private static final String AUTHORIZATION_HEADER = "Authorization";
     private final JWTUtil jwtUtil;
     private final AppConfig appConfig;
-    private final LoginUtil loginUtil;
+    private final LoginPolicyService loginPolicyService;
     private final RedisTemplate<String, String> redisTemplate;
     /**
      * @param jwtUtil JWT 유틸리티 클래스의 인스턴스
      *
      * JWTFilter 생성자
      */
-    public JWTFilter(JWTUtil jwtUtil, AppConfig appConfig, LoginUtil loginUtil, RedisTemplate<String, String> redisTemplate) {
+    public JWTFilter(JWTUtil jwtUtil, AppConfig appConfig, LoginPolicyService loginPolicyService, RedisTemplate<String, String> redisTemplate) {
         this.jwtUtil = jwtUtil;
         this.appConfig = appConfig;
-        this.loginUtil = loginUtil;
+        this.loginPolicyService = loginPolicyService;
         this.redisTemplate = redisTemplate;
     }
     /**
@@ -102,7 +101,7 @@
 
             // 중복 로그인 비허용 설정이면 Redis에서 최신 JWT 가져와 비교
             String userId = (String) jwtUtil.getClaim(accessToken, "mbrId");
-            if (!loginUtil.isAllowMultipleLogin()) {
+            if (!loginPolicyService.getPolicy()) {
                 String storedToken = redisTemplate.opsForValue().get("jwt:" + userId);
                 if (storedToken == null) {
                 } else if (!storedToken.equals(accessToken)) {
src/main/java/com/takensoft/common/filter/LoginFilter.java
--- src/main/java/com/takensoft/common/filter/LoginFilter.java
+++ src/main/java/com/takensoft/common/filter/LoginFilter.java
@@ -1,6 +1,8 @@
 package com.takensoft.common.filter;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.cms.loginPolicy.service.LoginModeService;
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
 import com.takensoft.cms.mber.dto.LoginDTO;
 import com.takensoft.cms.mber.service.LgnHstryService;
 import com.takensoft.cms.token.service.RefreshTokenService;
@@ -11,11 +13,11 @@
 import com.takensoft.common.exception.FilterExceptionHandler;
 import com.takensoft.common.util.HttpRequestUtil;
 import com.takensoft.common.util.JWTUtil;
-import com.takensoft.common.util.LoginUtil;
+import com.takensoft.common.util.SessionUtil;
+import jakarta.servlet.http.HttpSession;
 import lombok.SneakyThrows;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.http.HttpStatus;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
@@ -49,8 +51,9 @@
     private final RefreshTokenService refreshTokenService;
     private final LgnHstryService lgnHstryService;
     private final HttpRequestUtil httpRequestUtil;
-    private final AppConfig appConfig;
-    private final LoginUtil loginUtil;
+    private final LoginModeService loginModeService;
+    private final LoginPolicyService loginPolicyService;
+    private final SessionUtil sessionUtil;
 
     private static long JWT_ACCESSTIME; // access 토큰 유지 시간
     private static long JWT_REFRESHTIME; // refresh 토큰 유지 시간
@@ -67,15 +70,15 @@
      * LoginFilter 생성자
      */
     public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, LgnHstryService lgnHstryService, HttpRequestUtil httpRequestUtil,
-                       AppConfig appConfig, LoginUtil loginUtil, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate) {
+                      LoginModeService loginModeService,LoginPolicyService loginPolicyService,SessionUtil sessionUtil, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate) {
         this.authenticationManager = authenticationManager;
         this.jwtUtil = jwtUtil;
         this.refreshTokenService = refreshTokenService;
         this.lgnHstryService = lgnHstryService;
         this.httpRequestUtil = httpRequestUtil;
-        this.appConfig = appConfig;
-        this.loginUtil = loginUtil;
-
+        this.loginModeService = loginModeService;
+        this.loginPolicyService = loginPolicyService;
+        this.sessionUtil = sessionUtil;
         this.JWT_ACCESSTIME = aTime;
         this.JWT_REFRESHTIME = rTime;
         this.COOKIE_TIME = ctime;
@@ -121,7 +124,7 @@
      */
     @SneakyThrows
     @Override
-    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication authentication) {
+    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication authentication) throws IOException {
         MberVO mber = (MberVO) authentication.getPrincipal();
 
         // 로그인 이력 등록
@@ -138,6 +141,9 @@
         lgnHstryVO.setBrwsrNm(httpRequestUtil.getBrowser(httpRequestUtil.getUserAgent(req)));
         lgnHstryService.LgnHstrySave(lgnHstryVO);
 
+        // 로그인 방식 확인 JWT or SESSION
+        String loginType = loginModeService.getLoginMode();
+
         // 토큰 생성(access, refresh)
         String accessToken = jwtUtil.createJwt("Authorization", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_ACCESSTIME);
         String refreshToken = jwtUtil.createJwt("refresh", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_REFRESHTIME);
@@ -152,20 +158,29 @@
         }
         // refreshToken DB 저장
         refresh.setToken(refreshToken);
-        refreshTokenService.saveRefreshToken(req, res, refresh, JWT_REFRESHTIME);
 
-        // Redis에 AccessToken 저장 (중복 로그인 비허용 설정일 때)
-        if (!loginUtil.isAllowMultipleLogin()) {
-            redisTemplate.delete("jwt:" + mber.getMbrId()); // 기존 JWT 삭제
-            redisTemplate.opsForValue().set("jwt:" + mber.getMbrId(), accessToken, JWT_ACCESSTIME, TimeUnit.MILLISECONDS);
+
+        if ("S".equals(loginType)) {
+            HttpSession session = req.getSession(true);
+            session.setAttribute("JWT_TOKEN", accessToken);
+
+            // 중복 로그인 비허용일 때 기존 세션 만료
+            if (!loginPolicyService.getPolicy()) {
+                sessionUtil.registerSession(mber.getMbrId(), session);
+            }
+
+        } else {
+            res.setHeader("Authorization", accessToken);
+            res.addCookie(jwtUtil.createCookie("refresh", refreshToken, COOKIE_TIME));
+
+            // 중복 로그인 비허용일 때 Redis 저장
+            if (!loginPolicyService.getPolicy()) {
+                redisTemplate.delete("jwt:" + mber.getMbrId());
+                redisTemplate.opsForValue().set("jwt:" + mber.getMbrId(), accessToken, JWT_ACCESSTIME, TimeUnit.MILLISECONDS);
+            }
         }
-
-        // 응답설정
-        res.setHeader("Authorization", accessToken);
-//        res.setHeader("refresh", refreshToken);
-        // 쿠키 방식
-        res.addCookie(jwtUtil.createCookie("refresh",refreshToken, COOKIE_TIME));
-        res.setStatus(HttpStatus.OK.value());
+        refreshTokenService.saveRefreshToken(req, res, refresh, JWT_REFRESHTIME);
+        res.setHeader("login-type", loginType);
     }
 
     /**
src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
--- src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
+++ src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
@@ -1,10 +1,9 @@
 package com.takensoft.common.filter;
 
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
 import com.takensoft.cms.mber.vo.MberAuthorVO;
 import com.takensoft.cms.mber.vo.MberVO;
-import com.takensoft.common.config.RedisConfig;
 import com.takensoft.common.util.JWTUtil;
-import com.takensoft.common.util.LoginUtil;
 import jakarta.servlet.FilterChain;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
@@ -33,15 +32,11 @@
 
     private final JWTUtil jwtUtil;
     private final RedisTemplate<String, String> redisTemplate;
-    private final RedisConfig redisConfig;
-    private final LoginUtil loginUtil;
-    public SessionAuthFilter(JWTUtil jwtUtil,
-                             RedisTemplate<String, String> redisTemplate,
-                             RedisConfig redisConfig, LoginUtil loginUtil) {
+    private final LoginPolicyService loginPolicyService;
+    public SessionAuthFilter(JWTUtil jwtUtil, RedisTemplate<String, String> redisTemplate, LoginPolicyService loginPolicyService) {
         this.jwtUtil = jwtUtil;
         this.redisTemplate = redisTemplate;
-        this.redisConfig = redisConfig;
-        this.loginUtil = loginUtil;
+        this.loginPolicyService = loginPolicyService;
     }
     /**
      * @param request HttpServletRequest 객체
@@ -53,16 +48,7 @@
      * 세션 Filter 검증
      */
     @Override
-    protected void doFilterInternal(HttpServletRequest request,
-                                    HttpServletResponse response,
-                                    FilterChain filterChain) throws ServletException, IOException {
-
-        // JWT 방식이면 이 필터는 동작하지 않음
-        if (!"S".equalsIgnoreCase(loginUtil.getLoginMode())) {
-            filterChain.doFilter(request, response);
-            return;
-        }
-
+    protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
         HttpSession session = request.getSession(false);
         if (session == null || session.getAttribute("JWT_TOKEN") == null) {
             response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
@@ -78,7 +64,7 @@
         }
 
         // 중복 로그인 허용 여부 확인
-        if (!loginUtil.isAllowMultipleLogin()) {
+        if (!loginPolicyService.getPolicy()) {
             String mbrId = (String) jwtUtil.getClaim(accessToken, "mbrId");
             String storedToken = redisTemplate.opsForValue().get("jwt:" + mbrId);
             if (storedToken != null && !storedToken.equals(accessToken)) {
@@ -95,10 +81,9 @@
         mber.setMbrNm((String) jwtUtil.getClaim(accessToken, "mbrNm"));
         mber.setAuthorList(roles);
 
-        UsernamePasswordAuthenticationToken authentication =
-                new UsernamePasswordAuthenticationToken(mber, null, mber.getAuthorities());
+        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(mber, null, mber.getAuthorities());
 
-        SecurityContextHolder.getContext().setAuthentication(authentication);
+        SecurityContextHolder.getContext().setAuthentication(authToken);
 
         filterChain.doFilter(request, response);
     }
src/main/java/com/takensoft/common/idgen/context/ContextIdgen.java
--- src/main/java/com/takensoft/common/idgen/context/ContextIdgen.java
+++ src/main/java/com/takensoft/common/idgen/context/ContextIdgen.java
@@ -171,11 +171,11 @@
     // 로그인 방식
     @Bean(name = "loginModeIdgen")
     public IdgenService loginModeIdgen() {
-        IdgenService idgenService = new IdgenService();
-        idgenService.setCipers(15);
-        idgenService.setFillChar('0');
-        idgenService.setPrefix("LOGIN_MODE_");
-        idgenService.setTblNm("LOGIN_MODE_ID");
-        return idgenService;
+        IdgenService idgenServiceImpl = new IdgenService();
+        idgenServiceImpl.setCipers(15);
+        idgenServiceImpl.setFillChar('0');
+        idgenServiceImpl.setPrefix("LOGIN_MODE_");
+        idgenServiceImpl.setTblNm("LOGIN_MODE_ID");
+        return idgenServiceImpl;
     }
 }
(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/common/util/LoginUtil.java (deleted)
--- src/main/java/com/takensoft/common/util/LoginUtil.java
@@ -1,55 +0,0 @@
-package com.takensoft.common.util;
-
-import com.takensoft.cms.loginPolicy.service.LoginModeService;
-import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
-import org.springframework.stereotype.Component;
-
-/**
- * @author  : takensoft
- * @since   : 2025.01.22
- * @modification
- *     since    |    author    | description
- *  2025.01.22  |  takensoft   | 최초 등록
- *
- * 중복로그인, 로그인 방식 등의 유틸리티
- */
-@Component
-public class LoginUtil {
-
-
-    private final LoginPolicyService loginPolicyService;
-    private final LoginModeService loginModeService;
-    /**
-     *
-     * 기본 생성자
-     * @param loginPolicyService
-     * @param loginModeService
-     */
-    public LoginUtil(LoginPolicyService loginPolicyService, LoginModeService loginModeService) {
-        this.loginPolicyService = loginPolicyService;
-        this.loginModeService = loginModeService;
-    }
-
-    /**
-     * @return allowMultipleLogin - 중복로그인 허용/비허용 반환
-     *
-     * 중복 로그인 허용 여부를 반환하는 메서드
-     */
-    public boolean isAllowMultipleLogin() {
-        Boolean result = loginPolicyService.getPolicy();
-        return result;
-    }
-
-    /**
-     * @return allowMultipleLogin - 중복로그인 허용/비허용 반환
-     *
-     * 중복 로그인 허용 여부를 반환하는 메서드
-     */
-    public String getLoginMode() {
-        String result = loginModeService.getLoginMode();
-        return result;
-    }
-
-
-
-}
 
src/main/java/com/takensoft/common/util/SessionUtil.java (added)
+++ src/main/java/com/takensoft/common/util/SessionUtil.java
@@ -0,0 +1,38 @@
+package com.takensoft.common.util;
+
+import jakarta.servlet.http.HttpSession;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author  : takensoft
+ * @since   : 2025.01.22
+ * @modification
+ *     since    |    author    | description
+ *  2025.01.22  |  takensoft   | 최초 등록
+ *
+ * 중복로그인, 로그인 방식 등의 유틸리티
+ */
+@Component
+public class SessionUtil {
+
+        private final Map<String, HttpSession> sessionMap = new HashMap<>();
+
+        public synchronized void registerSession(String mbrId, HttpSession newSession) {
+            // 기존 세션 있으면 강제 로그아웃
+            HttpSession oldSession = sessionMap.get(mbrId);
+            if (oldSession != null && oldSession != newSession) {
+                oldSession.invalidate();
+            }
+            sessionMap.put(mbrId, newSession);
+        }
+
+        public void removeSession(String mbrId) {
+            sessionMap.remove(mbrId);
+        }
+
+
+
+}
Add a comment
List