From 0ea44c88f327c52b08fc1302f184a58f716a7263 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Thu, 13 Nov 2025 21:58:10 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D,=20=ED=8C=A8=EC=8A=A4=EC=9B=8C=EB=93=9C=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94,=20=ED=8C=A8=EC=8A=A4=EC=9B=8C=EB=93=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EC=95=8C=EB=A6=BC,=20=EA=B3=84=EC=A0=95?= =?UTF-8?q?=20=EC=B0=A8=EB=8B=A8=20=EC=95=8C=EB=A6=BC,=20=EB=B2=95?= =?UTF-8?q?=EC=9D=B8=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EC=B7=A8=EC=86=8C=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../apps/user/facade/UserManFacade.java | 23 ++++++++++++++ .../user/facade/UserRegisterFacadeImpl.java | 3 +- .../user/service/PortalUserAuthService.java | 5 ++-- .../portal/common/util/EncryptionUtil.java | 25 +++++++++++++++- .../PortalAuthenticationFailureHandler.java | 30 +++++++++++++++---- .../config/PortalAuthenticationManager.java | 19 ++++++++++-- .../views/apps/mypage/verificationEmail.html | 18 ++--------- 8 files changed, 95 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 17e8cca..2813ecc 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,4 @@ TODO.txt *.lck *.log +.claude \ No newline at end of file diff --git a/src/main/java/com/eactive/apim/portal/apps/user/facade/UserManFacade.java b/src/main/java/com/eactive/apim/portal/apps/user/facade/UserManFacade.java index dc7baa0..961578f 100644 --- a/src/main/java/com/eactive/apim/portal/apps/user/facade/UserManFacade.java +++ b/src/main/java/com/eactive/apim/portal/apps/user/facade/UserManFacade.java @@ -10,6 +10,7 @@ import com.eactive.apim.portal.common.util.SecurityUtil; import com.eactive.apim.portal.common.util.StringMaskingUtil; import com.eactive.apim.portal.invitation.entity.UserInvitation; import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus; +import com.eactive.apim.portal.invitation.event.UserInvitationCancelEvent; import com.eactive.apim.portal.invitation.event.UserInvitationEvent; import com.eactive.apim.portal.portaluser.event.UserManagerAssignedEvent; import com.eactive.apim.portal.invitation.repository.UserInvitationRepository; @@ -183,7 +184,29 @@ public class UserManFacade { throw new IllegalStateException("Invitation is not in a cancelable state"); } + // invitationId 로 사용자 이름 조회, 실패시 id 를 이름으로 대체 + String name = portalUserRepository.findById(invitation.getInvitationEmail()) + .map(PortalUser::getUserName) + .orElse(invitation.getInvitationEmail()); + + // name 이 이메일 일 경우 @ 앞부분 만 사용 (안하면 암호화 해야함...) + if (name.contains("@")) { + name = name.substring(0, name.indexOf("@")); + } + invitation.setStatus(InvitationStatus.CANCELED); + + messageHandlerService.publishEvent(UserInvitationCancelEvent.KEY, + MessageRecipient.builder() + .username(name) + .userId(invitationId) + .build(), + new HashMap() {{ + put("corpName", user.getPortalOrg().getOrgName()); + put("managerName", user.getUserName()); + }} + ); + userInvitationRepository.save(invitation); } diff --git a/src/main/java/com/eactive/apim/portal/apps/user/facade/UserRegisterFacadeImpl.java b/src/main/java/com/eactive/apim/portal/apps/user/facade/UserRegisterFacadeImpl.java index 8c06d09..f28e68c 100644 --- a/src/main/java/com/eactive/apim/portal/apps/user/facade/UserRegisterFacadeImpl.java +++ b/src/main/java/com/eactive/apim/portal/apps/user/facade/UserRegisterFacadeImpl.java @@ -146,7 +146,8 @@ public class UserRegisterFacadeImpl implements UserRegisterFacade { } agreementsFacade.saveUserAgreements(newUser.getId(), AgreementType.PRIVACY_COLLECT_IND); - sendEmailActivation(newUser); + // 11.13 - 회원 가입단계가 아닌 로그인 단계로 이메일 인증 이동 + // sendEmailActivation(newUser); return new ValidationResponse(true,"회원가입이 완료되었습니다."); } diff --git a/src/main/java/com/eactive/apim/portal/apps/user/service/PortalUserAuthService.java b/src/main/java/com/eactive/apim/portal/apps/user/service/PortalUserAuthService.java index c69dc2b..3ec73a5 100644 --- a/src/main/java/com/eactive/apim/portal/apps/user/service/PortalUserAuthService.java +++ b/src/main/java/com/eactive/apim/portal/apps/user/service/PortalUserAuthService.java @@ -96,9 +96,10 @@ public class PortalUserAuthService implements UserDetailsService { public void initializePassword(String loginId, String userName, String mobileNumber) { - PortalUser portalUser = portalUserRepository.findByLoginIdAndUserNameAndMobileNumber(loginId, userName, mobileNumber).orElseThrow(() -> new UserNotFoundException("일치하는 사용자 정보를 찾을 수 없습니다.")); + PortalUser portalUser = portalUserRepository.findByLoginIdAndUserNameAndMobileNumber(loginId, userName, mobileNumber) + .orElseThrow(() -> new UserNotFoundException("일치하는 사용자 정보를 찾을 수 없습니다.")); - String tempPassword = EncryptionUtil.generateNewPassword(); + String tempPassword = EncryptionUtil.generateNewPasswordForKjbank(loginId); portalUser.setPasswordHash(passwordEncoder.encode(tempPassword)); portalUserRepository.save(portalUser); diff --git a/src/main/java/com/eactive/apim/portal/common/util/EncryptionUtil.java b/src/main/java/com/eactive/apim/portal/common/util/EncryptionUtil.java index 365514c..bc02ff7 100644 --- a/src/main/java/com/eactive/apim/portal/common/util/EncryptionUtil.java +++ b/src/main/java/com/eactive/apim/portal/common/util/EncryptionUtil.java @@ -30,7 +30,30 @@ public class EncryptionUtil { return newpassword.toString(); } - @Value("${encryption.key:kbank_portal_application_1357902}") + /** + * 광주은행용 임시패스워드 생성 + * - @ + 이메일 주소 앞 5자리 + 랜덤숫자 3자리 + ! + * @return + */ + public static String generateNewPasswordForKjbank(String loginId) { + StringBuilder newpassword = new StringBuilder(); + newpassword.append("@"); + + if (loginId.length() <= 5) { + newpassword.append(loginId); + } else { + newpassword.append(loginId.substring(0, 5)); + } + + for (int i = 1; i <= 3; i++) { + newpassword.append(RandomUtil.getRandomNum(0, 9)); + } + newpassword.append("!"); + + return newpassword.toString(); + } + + @Value("${encryption.key:kjbank_portal_application_1357902}") private String secretKey; // Should be 16, 24, or 32 bytes long for AES-128, AES-192, or AES-256 private static final String ALGORITHM = "AES"; diff --git a/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationFailureHandler.java b/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationFailureHandler.java index e2bb337..c6d6f2e 100644 --- a/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationFailureHandler.java +++ b/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationFailureHandler.java @@ -5,11 +5,10 @@ import com.eactive.apim.portal.apps.user.service.PortalUserLogService; import com.eactive.apim.portal.common.exception.UserNotFoundException; import com.eactive.apim.portal.portaluser.entity.PortalUser; import com.eactive.apim.portal.portaluser.repository.PortalUserRepository; -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - +import com.eactive.apim.portal.template.entity.MessageCode; +import com.eactive.apim.portal.template.service.MessageHandlerService; +import com.eactive.apim.portal.template.service.MessageRecipient; +import org.apache.groovy.util.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.AuthenticationException; @@ -20,6 +19,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + /** * Created by Sungpil Hyun */ @@ -30,10 +34,15 @@ public class PortalAuthenticationFailureHandler implements AuthenticationFailure private static final Logger logger = LoggerFactory.getLogger(PortalAuthenticationFailureHandler.class); private final PortalUserRepository portalUserRepository; private final PortalUserLogService userLogService; + private final MessageHandlerService messageHandlerService; - public PortalAuthenticationFailureHandler(PortalUserRepository portalUserRepository, PortalUserLogService userLogService) { + + public PortalAuthenticationFailureHandler(PortalUserRepository portalUserRepository, + PortalUserLogService userLogService, + MessageHandlerService messageHandlerService) { this.portalUserRepository = portalUserRepository; this.userLogService = userLogService; + this.messageHandlerService = messageHandlerService; } @Override @@ -53,8 +62,17 @@ public class PortalAuthenticationFailureHandler implements AuthenticationFailure user.setLoginFailureCount(user.getLoginFailureCount() + 1); if (user.getLoginFailureCount() >= 5) { user.setAccountLockYn("Y"); + + // 계정 잠금 알림 + messageHandlerService.publishEvent( + MessageCode.USER_ACCOUNT_LOCKED, + MessageRecipient.of(user), + Maps.of("reason", "5회 이상 로그인 실패로 인한 계정 잠금")) ;; } portalUserRepository.save(user); + + + } catch (UserNotFoundException e) { logger.error("{} login try {}", username, e.getMessage()); } diff --git a/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationManager.java b/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationManager.java index b9828a0..b8955a5 100644 --- a/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationManager.java +++ b/src/main/java/com/eactive/apim/portal/config/PortalAuthenticationManager.java @@ -5,8 +5,12 @@ import com.eactive.apim.portal.apps.user.service.PortalUserAuthService; import com.eactive.apim.portal.common.user.PortalAuthenticatedUser; import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums; import com.eactive.apim.portal.portaluser.entity.PortalUserEnums; +import com.eactive.apim.portal.template.entity.MessageCode; +import com.eactive.apim.portal.template.service.MessageHandlerService; +import com.eactive.apim.portal.template.service.MessageRecipient; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.groovy.util.Maps; import org.springframework.security.authentication.*; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -25,6 +29,7 @@ public class PortalAuthenticationManager implements AuthenticationManager { private final PortalUserAuthService portalUserAuthService; private final PasswordEncoder passwordEncoder; + private final MessageHandlerService messageHandlerService; private String decodePassword(String encodedPassword) { try { @@ -46,6 +51,16 @@ public class PortalAuthenticationManager implements AuthenticationManager { PortalAuthenticatedUser user = (PortalAuthenticatedUser) portalUserAuthService.loadUserByUsername(username); + + if (!user.isAccountNonLocked()) { + if (user.getLoginFailureCount() >= 5) { + throw new LockedException("계정이 잠겼습니다. 비밀번호 초기화 또는 관리자에게 문의하세요."); + } + + throw new LockedException("로그인 할 수 없습니다. 비밀번호 초기화 또는 관리자에게 문의하세요."); + } + + // 비밀번호 검증 if (!passwordEncoder.matches(decodedPassword, user.getPassword())) { // 암호화가 되어 있지 않을 수도 있어 그대로 비교 검증 @@ -83,9 +98,7 @@ public class PortalAuthenticationManager implements AuthenticationManager { } } - if (!user.isAccountNonLocked()) { - throw new LockedException("로그인 할 수 없습니다. 비밀번호 초기화 또는 관리자에게 문의하세요."); - } + UsernamePasswordAuthenticationToken authorityToken = new UsernamePasswordAuthenticationToken(user, decodedPassword, user.getAuthorities()); diff --git a/src/main/resources/templates/views/apps/mypage/verificationEmail.html b/src/main/resources/templates/views/apps/mypage/verificationEmail.html index 85cdf6f..89fc23a 100644 --- a/src/main/resources/templates/views/apps/mypage/verificationEmail.html +++ b/src/main/resources/templates/views/apps/mypage/verificationEmail.html @@ -61,26 +61,12 @@
취소 -
- + +
- - - - - - - - - - - - - -