하석형 하석형 05-27
250527 하석형 이메일 2차 인증 사용 여부 설정
@19c41cfda1081061b36153d51e7f7d8d0e18464d
 
src/main/java/com/takensoft/cms/loginPolicy/dao/Email2ndAuthDAO.java (added)
+++ src/main/java/com/takensoft/cms/loginPolicy/dao/Email2ndAuthDAO.java
@@ -0,0 +1,33 @@
+package com.takensoft.cms.loginPolicy.dao;
+
+import com.takensoft.cms.loginPolicy.vo.Email2ndAuthVO;
+import com.takensoft.cms.loginPolicy.vo.LoginModeVO;
+import org.egovframe.rte.psl.dataaccess.mapper.Mapper;
+
+/**
+ * @author 하석형
+ * @since 2025.05.27
+ * @modification
+ *     since    |    author    | description
+ *  2025.05.27  |    하석형     | 최초 등록
+ *
+ * 이메일 2차 인증 관련 DAO
+ */
+@Mapper("email2ndAuthDAO")
+public interface Email2ndAuthDAO {
+
+    /**
+     * @return String - 이메일 2차 인증 사용 여부
+     *
+     * 이메일 2차 인증 조회
+     */
+    String findLatestEmail2ndAuth();
+
+    /**
+     * @param email2ndAuthVO - 이메일 2차 인증 정보
+     * @return int - 이메일 2차 인증 등록 결과
+     *
+     * 이메일 2차 인증 등록
+     */
+    int save(Email2ndAuthVO email2ndAuthVO);
+}
 
src/main/java/com/takensoft/cms/loginPolicy/service/Email2ndAuthService.java (added)
+++ src/main/java/com/takensoft/cms/loginPolicy/service/Email2ndAuthService.java
@@ -0,0 +1,34 @@
+package com.takensoft.cms.loginPolicy.service;
+
+import com.takensoft.cms.loginPolicy.vo.Email2ndAuthVO;
+import com.takensoft.cms.loginPolicy.vo.LoginPolicyVO;
+
+/**
+ * @author 하석형
+ * @since 2025.05.27
+ * @modification
+ *     since    |    author    | description
+ *  2025.05.27  |    하석형     | 최초 등록
+ *
+ * 이메일 2차 인증 관련 인터페이스
+ */
+public interface Email2ndAuthService {
+
+    /**
+     *
+     * @return boolean - 이메일 2차 인증 사용 여부 조회
+     *
+     * 이메일 2차 인증 조회
+     */
+    public boolean findByEmail2ndAuth();
+
+    /**
+     * @param email2ndAuthVO - 이메일 2차 인증 정보
+     * @return int - 이메일 2차 인증 등록 결과
+     *
+     * 이메일 2차 인증 등록
+     */
+    public int email2ndAuthSave(Email2ndAuthVO email2ndAuthVO);
+
+
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/cms/loginPolicy/service/impl/Email2ndAuthServiceImpl.java (added)
+++ src/main/java/com/takensoft/cms/loginPolicy/service/impl/Email2ndAuthServiceImpl.java
@@ -0,0 +1,95 @@
+package com.takensoft.cms.loginPolicy.service.impl;
+
+import com.takensoft.cms.loginPolicy.dao.Email2ndAuthDAO;
+import com.takensoft.cms.loginPolicy.dao.LoginPolicyDAO;
+import com.takensoft.cms.loginPolicy.service.Email2ndAuthService;
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
+import com.takensoft.cms.loginPolicy.vo.Email2ndAuthVO;
+import com.takensoft.cms.loginPolicy.vo.LoginPolicyVO;
+import com.takensoft.common.exception.CustomInsertFailException;
+import com.takensoft.common.exception.CustomNotFoundException;
+import com.takensoft.common.idgen.service.IdgenService;
+import com.takensoft.common.service.VerificationService;
+import lombok.RequiredArgsConstructor;
+import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author 하석형
+ * @since 2025.05.27
+ * @modification
+ *     since    |    author    | description
+ *  2025.05.27  |    하석형     | 최초 등록
+ *
+ * EgovAbstractServiceImpl : 전자정부 상속
+ * Email2ndAuthService : 이메일 2차 인증 관련 인터페이스 상속
+ *
+ * 이메일 2차 인증 관련 인터페이스 구현체
+ */
+@Service("email2ndAuthService")
+@RequiredArgsConstructor
+public class Email2ndAuthServiceImpl extends EgovAbstractServiceImpl implements Email2ndAuthService {
+
+    private final Email2ndAuthDAO email2ndAuthDAO;
+    private final IdgenService eml2ndAuthIdgn;
+    private final VerificationService verificationService;
+
+    /**
+     * @return Boolean - 이메일 2차 인증 사용 여부
+     * @throws DataAccessException - db 관련 예외 발생 시
+     * @throws Exception - 그 외 예외 발생 시
+     *
+     * 이메일 2차 인증 조회
+     */
+    @Override
+    public boolean findByEmail2ndAuth() {
+        try {
+            String useEmail2ndAuth = email2ndAuthDAO.findLatestEmail2ndAuth();
+
+            if (useEmail2ndAuth.equals("Y")) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (DataAccessException dae) {
+            throw dae;
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    /**
+     * @param email2ndAuthVO - 이메일 2차 인증 정보
+     * @return int - 이메일 2차 인증 등록 결과
+     * @throws CustomInsertFailException - 이메일 2차 인증 등록 예외 발생 시
+     * @throws DataAccessException - db 관련 예외 발생 시
+     * @throws Exception - 그 외 예외 발생 시
+     *
+     * 이메일 2차 인증 등록
+     */
+    @Override
+    public int email2ndAuthSave(Email2ndAuthVO email2ndAuthVO) {
+        try {
+            // 등록된 토큰에서 사용자 정보 조회
+            String writer = verificationService.getCurrentUserId();
+            if (writer == null || writer.isEmpty()) {
+                throw new CustomNotFoundException("사용자 정보 조회에 실패했습니다.");
+            }
+            email2ndAuthVO.setRgtr(writer);
+
+            email2ndAuthVO.setEml2ndAuthId(eml2ndAuthIdgn.getNextStringId()); // ID 자동 생성
+            int result = email2ndAuthDAO.save(email2ndAuthVO);
+            if(result == 0) {
+                throw new CustomInsertFailException("이메일 2차 인증 등록에 실패했습니다.");
+            }
+
+            return result;
+        } catch (DataAccessException dae) {
+            throw dae;
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/cms/loginPolicy/vo/Email2ndAuthVO.java (added)
+++ src/main/java/com/takensoft/cms/loginPolicy/vo/Email2ndAuthVO.java
@@ -0,0 +1,27 @@
+package com.takensoft.cms.loginPolicy.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author 하석형
+ * @since 2025.05.27
+ * @modification
+ *     since    |    author    | description
+ *  2025.05.27  |    하석형     | 최초 등록
+ *
+ * 이메일 2차 인증 관련 VO
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class Email2ndAuthVO {
+
+    private String eml2ndAuthId;     // 이메일 2차 인증 ID
+    private String useYn;            // 사용 여부
+    private String rgtr;             // 등록자 ID
+    private String regDt;            // 등록일시
+}(파일 끝에 줄바꿈 문자 없음)
src/main/java/com/takensoft/cms/loginPolicy/web/LoginPolicyController.java
--- src/main/java/com/takensoft/cms/loginPolicy/web/LoginPolicyController.java
+++ src/main/java/com/takensoft/cms/loginPolicy/web/LoginPolicyController.java
@@ -1,7 +1,9 @@
 package com.takensoft.cms.loginPolicy.web;
 
+import com.takensoft.cms.loginPolicy.service.Email2ndAuthService;
 import com.takensoft.cms.loginPolicy.service.LoginModeService;
 import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
+import com.takensoft.cms.loginPolicy.vo.Email2ndAuthVO;
 import com.takensoft.cms.loginPolicy.vo.LoginModeVO;
 import com.takensoft.cms.loginPolicy.vo.LoginPolicyVO;
 import com.takensoft.cms.mber.vo.MberVO;
@@ -10,6 +12,7 @@
 import com.takensoft.common.util.JWTUtil;
 import com.takensoft.common.util.ResponseUtil;
 import com.takensoft.common.util.SessionUtil;
+import com.takensoft.common.verify.vo.EmailVO;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -29,6 +32,7 @@
  * @modification
  *     since    |    author    | description
  *  2025.03.22  |    김혜민     | 최초 등록
+ *  2025.05.27  |    하석형     | findByEmail2ndAuth, saveEmail2ndAuth 추가
  *
  * 로그인정책 관련 컨트롤러
  */
@@ -45,6 +49,7 @@
     private final SessionUtil sessionUtil;
     private final RedisTemplate<String, String> redisTemplate;
     private final RefreshTokenService refreshTokenService;
+    private final Email2ndAuthService email2ndAuth;
 
     /**
      *
@@ -159,4 +164,29 @@
         }
     }
 
+    /**
+     * @return ResponseEntity - 이메일 2차 인증 조회 결과를 포함하는 응답
+     *
+     * 이메일 2차 인증 조회
+     */
+    @PostMapping("/findByEmail2ndAuth.json")
+    public ResponseEntity<?> findByEmail2ndAuth() {
+        boolean result = email2ndAuth.findByEmail2ndAuth();
+
+        return resUtil.successRes(result, MessageCode.COMMON_SUCCESS);
+    }
+
+    /**
+     * @param email2ndAuthVO - 이메일 2차 인증 정보
+     * @return ResponseEntity - 이메일 2차 인증 등록 결과를 포함하는 응답
+     *
+     * 이메일 2차 인증 등록
+     */
+    @PostMapping("/saveEmail2ndAuth.json")
+    public ResponseEntity<?> saveEmail2ndAuth(@RequestBody Email2ndAuthVO email2ndAuthVO) {
+        int result = email2ndAuth.email2ndAuthSave(email2ndAuthVO);
+
+        return resUtil.successRes(result, MessageCode.COMMON_SUCCESS);
+    }
+
 }
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
@@ -2,6 +2,7 @@
 
 import com.takensoft.cms.accesCtrl.service.AccesCtrlService;
 import com.takensoft.cms.cntxtPth.service.CntxtPthService;
+import com.takensoft.cms.loginPolicy.service.Email2ndAuthService;
 import com.takensoft.cms.loginPolicy.service.LoginModeService;
 import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
 import com.takensoft.common.filter.*;
@@ -62,6 +63,7 @@
     private final LoginPolicyService loginPolicyService;
     private final EmailServiceImpl emailServiceImpl;
     private final LoginUtil loginUtil;
+    private final Email2ndAuthService email2ndAuth;
 
     @Autowired
     private CustomOAuth2UserServiceImpl customOAuth2UserServiceImpl;
@@ -80,7 +82,7 @@
      * SecurityConfig 생성자
      */
     public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, CntxtPthService cntxtPthService, AccesCtrlService accesCtrlService, AppConfig appConfig, CustomAuthenticationEntryPoint authenticationEntryPoint, CustomAccessDenieHandler accessDenieHandler,
-                          HttpRequestUtil httpRequestUtil, LoginModeService loginModeService, LoginPolicyService loginPolicyService, EmailServiceImpl emailServiceImpl, @Value("${front.url}") String fUrl, RedisTemplate<String, String> redisTemplate, LoginUtil loginUtil) {
+                          HttpRequestUtil httpRequestUtil, LoginModeService loginModeService, LoginPolicyService loginPolicyService, EmailServiceImpl emailServiceImpl, @Value("${front.url}") String fUrl, RedisTemplate<String, String> redisTemplate, LoginUtil loginUtil, Email2ndAuthService email2ndAuth) {
         this.authenticationConfiguration = authenticationConfiguration;
         this.cntxtPthService = cntxtPthService;
         this.accesCtrlService = accesCtrlService;
@@ -91,10 +93,11 @@
         this.appConfig = appConfig;
         this.loginModeService = loginModeService;
         this.loginPolicyService = loginPolicyService;
-        this.emailServiceImpl = emailServiceImpl;
         this.FRONT_URL = fUrl;
         this.redisTemplate = redisTemplate;
+        this.emailServiceImpl = emailServiceImpl;
         this.loginUtil = loginUtil;
+        this.email2ndAuth = email2ndAuth;
     }
 
     /**
@@ -189,7 +192,7 @@
         http.addFilterBefore(new AccesFilter(accesCtrlService, httpRequestUtil, appConfig), JWTFilter.class);
 
         // 로그인 필터
-        http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), emailServiceImpl, loginUtil), UsernamePasswordAuthenticationFilter.class);
+        http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), emailServiceImpl, loginUtil, email2ndAuth), UsernamePasswordAuthenticationFilter.class);
 
 
         return http.build();
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,7 @@
 package com.takensoft.common.filter;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.cms.loginPolicy.service.Email2ndAuthService;
 import com.takensoft.cms.mber.dto.LoginDTO;
 import com.takensoft.cms.mber.vo.MberVO;
 import com.takensoft.common.exception.FilterExceptionHandler;
@@ -40,13 +41,15 @@
     private final AuthenticationManager authenticationManager;
     private final EmailServiceImpl emailServiceImpl;
     private final LoginUtil loginUtil;
+    private final Email2ndAuthService email2ndAuth;
     /**
      * LoginFilter 생성자
      */
-    public LoginFilter(AuthenticationManager authenticationManager, EmailServiceImpl emailServiceImpl, LoginUtil loginUtil) {
+    public LoginFilter(AuthenticationManager authenticationManager, EmailServiceImpl emailServiceImpl, LoginUtil loginUtil, Email2ndAuthService email2ndAuth) {
         this.authenticationManager = authenticationManager;
         this.emailServiceImpl = emailServiceImpl;
         this.loginUtil = loginUtil;
+        this.email2ndAuth = email2ndAuth;
 
         this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/mbr/loginProc.json","POST"));
     }
@@ -94,22 +97,27 @@
         MberVO mber = (MberVO) authentication.getPrincipal();
         boolean isAdmin = mber.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN")); // 관리자 권한 여부
         String lgnReqPage = (String) req.getAttribute("lgnReqPage"); // 로그인 요청 페이지 정보 (A: 관리자, U: 사용자)
+        boolean use2ndAuth = email2ndAuth.findByEmail2ndAuth(); // 이메일 2차 인증 여부 확인
 
         // 관리자일 경우 2차 인증(이메일 인증) 코드 발송
         if(isAdmin) {
-            EmailVO emailVO = new EmailVO().builder()
-                    .email(mber.getEml())
-                    .build();
-            emailServiceImpl.sendEmailVerifyCode(emailVO);
-            res.setContentType("application/json;charset=UTF-8");
-            res.setStatus(HttpStatus.OK.value());
-            result.put("mbrId", mber.getMbrId());
-            result.put("email", mber.getEml());
+            if(use2ndAuth) {
+                EmailVO emailVO = new EmailVO().builder()
+                        .email(mber.getEml())
+                        .build();
+                emailServiceImpl.sendEmailVerifyCode(emailVO);
+                res.setContentType("application/json;charset=UTF-8");
+                res.setStatus(HttpStatus.OK.value());
+                result.put("mbrId", mber.getMbrId());
+                result.put("email", mber.getEml());
 
-            res.setContentType("application/json;charset=UTF-8");
-            res.setStatus(HttpStatus.OK.value());
+                res.setContentType("application/json;charset=UTF-8");
+                res.setStatus(HttpStatus.OK.value());
 
-            new ObjectMapper().writeValue(res.getOutputStream(), result);
+                new ObjectMapper().writeValue(res.getOutputStream(), result);
+            } else {
+                loginUtil.successLogin(mber, req, res); // 로그인 성공 처리
+            }
         // 사용자일 경우
         } else {
             // 사용자가 관리자 로그인 페이지로 접근할 경우
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
@@ -181,7 +181,7 @@
 
     // 컨텍스트 패스 관리
     @Bean(name = "cntxtPthIdgn")
-    public IdgenService cntxtPthIdgnIdgen() {
+    public IdgenService cntxtPthIdgn() {
         IdgenService idgenServiceImpl = new IdgenService();
         idgenServiceImpl.setCipers(15);
         idgenServiceImpl.setFillChar('0');
@@ -189,4 +189,15 @@
         idgenServiceImpl.setTblNm("CNTXT_PTH_ID");
         return idgenServiceImpl;
     }
+
+    // 이메일 2차 인증 관리
+    @Bean(name = "eml2ndAuthIdgn")
+    public IdgenService eml2ndAuthIdgn() {
+        IdgenService idgenServiceImpl = new IdgenService();
+        idgenServiceImpl.setCipers(15);
+        idgenServiceImpl.setFillChar('0');
+        idgenServiceImpl.setPrefix("EML_2ND_AUTH_");
+        idgenServiceImpl.setTblNm("EML_2ND_AUTH_ID");
+        return idgenServiceImpl;
+    }
 }
(파일 끝에 줄바꿈 문자 없음)
 
src/main/resources/mybatis/mapper/loginPolicy/email2ndAuth-SQL.xml (added)
+++ src/main/resources/mybatis/mapper/loginPolicy/email2ndAuth-SQL.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+    작성자 : 하석형
+    작성일 : 2025.05.27
+    내 용 : 이메일 2차 인증 관련
+-->
+<mapper namespace="com.takensoft.cms.loginPolicy.dao.Email2ndAuthDAO">
+
+    <!--
+        작성자 : 하석형
+        작성일 : 2025.05.27
+        내 용 : 이메일 2차 인증 사용 여부 최신값 조회
+    -->
+    <select id="findLatestEmail2ndAuth" resultType="String">
+        SELECT use_yn
+        FROM eml_2nd_auth_hstry
+        ORDER BY reg_dt DESC
+        LIMIT 1
+    </select>
+
+    <!--
+        작성자 : 하석형
+        작성일 : 2025.05.27
+        내 용 : 이메일 2차 인증 등록
+    -->
+    <insert id="save" parameterType="Email2ndAuthVO">
+        INSERT INTO eml_2nd_auth_hstry (
+            eml_2nd_auth_id,
+            use_yn,
+            rgtr,
+            reg_dt
+        )
+        VALUES (
+            #{eml2ndAuthId},
+            #{useYn},
+            #{rgtr},
+            NOW()
+        )
+    </insert>
+
+</mapper>(파일 끝에 줄바꿈 문자 없음)
Add a comment
List