이메일 인증, 패스워드 초기화, 패스워드 변경 알림, 계정 차단 알림, 법인 사용자 초대 취소 완료
This commit is contained in:
@@ -101,3 +101,4 @@ TODO.txt
|
|||||||
|
|
||||||
*.lck
|
*.lck
|
||||||
*.log
|
*.log
|
||||||
|
.claude
|
||||||
@@ -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.common.util.StringMaskingUtil;
|
||||||
import com.eactive.apim.portal.invitation.entity.UserInvitation;
|
import com.eactive.apim.portal.invitation.entity.UserInvitation;
|
||||||
import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus;
|
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.invitation.event.UserInvitationEvent;
|
||||||
import com.eactive.apim.portal.portaluser.event.UserManagerAssignedEvent;
|
import com.eactive.apim.portal.portaluser.event.UserManagerAssignedEvent;
|
||||||
import com.eactive.apim.portal.invitation.repository.UserInvitationRepository;
|
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");
|
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);
|
invitation.setStatus(InvitationStatus.CANCELED);
|
||||||
|
|
||||||
|
messageHandlerService.publishEvent(UserInvitationCancelEvent.KEY,
|
||||||
|
MessageRecipient.builder()
|
||||||
|
.username(name)
|
||||||
|
.userId(invitationId)
|
||||||
|
.build(),
|
||||||
|
new HashMap<String, Object>() {{
|
||||||
|
put("corpName", user.getPortalOrg().getOrgName());
|
||||||
|
put("managerName", user.getUserName());
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
|
||||||
userInvitationRepository.save(invitation);
|
userInvitationRepository.save(invitation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,8 @@ public class UserRegisterFacadeImpl implements UserRegisterFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
agreementsFacade.saveUserAgreements(newUser.getId(), AgreementType.PRIVACY_COLLECT_IND);
|
agreementsFacade.saveUserAgreements(newUser.getId(), AgreementType.PRIVACY_COLLECT_IND);
|
||||||
sendEmailActivation(newUser);
|
// 11.13 - 회원 가입단계가 아닌 로그인 단계로 이메일 인증 이동
|
||||||
|
// sendEmailActivation(newUser);
|
||||||
return new ValidationResponse(true,"회원가입이 완료되었습니다.");
|
return new ValidationResponse(true,"회원가입이 완료되었습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,9 +96,10 @@ public class PortalUserAuthService implements UserDetailsService {
|
|||||||
|
|
||||||
public void initializePassword(String loginId, String userName, String mobileNumber) {
|
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));
|
portalUser.setPasswordHash(passwordEncoder.encode(tempPassword));
|
||||||
|
|
||||||
portalUserRepository.save(portalUser);
|
portalUserRepository.save(portalUser);
|
||||||
|
|||||||
@@ -30,7 +30,30 @@ public class EncryptionUtil {
|
|||||||
return newpassword.toString();
|
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 String secretKey; // Should be 16, 24, or 32 bytes long for AES-128, AES-192, or AES-256
|
||||||
|
|
||||||
private static final String ALGORITHM = "AES";
|
private static final String ALGORITHM = "AES";
|
||||||
|
|||||||
+24
-6
@@ -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.common.exception.UserNotFoundException;
|
||||||
import com.eactive.apim.portal.portaluser.entity.PortalUser;
|
import com.eactive.apim.portal.portaluser.entity.PortalUser;
|
||||||
import com.eactive.apim.portal.portaluser.repository.PortalUserRepository;
|
import com.eactive.apim.portal.portaluser.repository.PortalUserRepository;
|
||||||
import java.io.IOException;
|
import com.eactive.apim.portal.template.entity.MessageCode;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import com.eactive.apim.portal.template.service.MessageHandlerService;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import com.eactive.apim.portal.template.service.MessageRecipient;
|
||||||
import javax.servlet.http.HttpSession;
|
import org.apache.groovy.util.Maps;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
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.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
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
|
* Created by Sungpil Hyun
|
||||||
*/
|
*/
|
||||||
@@ -30,10 +34,15 @@ public class PortalAuthenticationFailureHandler implements AuthenticationFailure
|
|||||||
private static final Logger logger = LoggerFactory.getLogger(PortalAuthenticationFailureHandler.class);
|
private static final Logger logger = LoggerFactory.getLogger(PortalAuthenticationFailureHandler.class);
|
||||||
private final PortalUserRepository portalUserRepository;
|
private final PortalUserRepository portalUserRepository;
|
||||||
private final PortalUserLogService userLogService;
|
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.portalUserRepository = portalUserRepository;
|
||||||
this.userLogService = userLogService;
|
this.userLogService = userLogService;
|
||||||
|
this.messageHandlerService = messageHandlerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -53,8 +62,17 @@ public class PortalAuthenticationFailureHandler implements AuthenticationFailure
|
|||||||
user.setLoginFailureCount(user.getLoginFailureCount() + 1);
|
user.setLoginFailureCount(user.getLoginFailureCount() + 1);
|
||||||
if (user.getLoginFailureCount() >= 5) {
|
if (user.getLoginFailureCount() >= 5) {
|
||||||
user.setAccountLockYn("Y");
|
user.setAccountLockYn("Y");
|
||||||
|
|
||||||
|
// 계정 잠금 알림
|
||||||
|
messageHandlerService.publishEvent(
|
||||||
|
MessageCode.USER_ACCOUNT_LOCKED,
|
||||||
|
MessageRecipient.of(user),
|
||||||
|
Maps.of("reason", "5회 이상 로그인 실패로 인한 계정 잠금")) ;;
|
||||||
}
|
}
|
||||||
portalUserRepository.save(user);
|
portalUserRepository.save(user);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (UserNotFoundException e) {
|
} catch (UserNotFoundException e) {
|
||||||
logger.error("{} login try {}", username, e.getMessage());
|
logger.error("{} login try {}", username, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.common.user.PortalAuthenticatedUser;
|
||||||
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums;
|
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums;
|
||||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums;
|
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.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.groovy.util.Maps;
|
||||||
import org.springframework.security.authentication.*;
|
import org.springframework.security.authentication.*;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
@@ -25,6 +29,7 @@ public class PortalAuthenticationManager implements AuthenticationManager {
|
|||||||
|
|
||||||
private final PortalUserAuthService portalUserAuthService;
|
private final PortalUserAuthService portalUserAuthService;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
private final MessageHandlerService messageHandlerService;
|
||||||
|
|
||||||
private String decodePassword(String encodedPassword) {
|
private String decodePassword(String encodedPassword) {
|
||||||
try {
|
try {
|
||||||
@@ -46,6 +51,16 @@ public class PortalAuthenticationManager implements AuthenticationManager {
|
|||||||
|
|
||||||
PortalAuthenticatedUser user = (PortalAuthenticatedUser) portalUserAuthService.loadUserByUsername(username);
|
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())) {
|
if (!passwordEncoder.matches(decodedPassword, user.getPassword())) {
|
||||||
// 암호화가 되어 있지 않을 수도 있어 그대로 비교 검증
|
// 암호화가 되어 있지 않을 수도 있어 그대로 비교 검증
|
||||||
@@ -83,9 +98,7 @@ public class PortalAuthenticationManager implements AuthenticationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.isAccountNonLocked()) {
|
|
||||||
throw new LockedException("로그인 할 수 없습니다. 비밀번호 초기화 또는 관리자에게 문의하세요.");
|
|
||||||
}
|
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authorityToken =
|
UsernamePasswordAuthenticationToken authorityToken =
|
||||||
new UsernamePasswordAuthenticationToken(user, decodedPassword, user.getAuthorities());
|
new UsernamePasswordAuthenticationToken(user, decodedPassword, user.getAuthorities());
|
||||||
|
|||||||
@@ -61,26 +61,12 @@
|
|||||||
<!-- 제출 버튼 -->
|
<!-- 제출 버튼 -->
|
||||||
<div class="btn_application m_top">
|
<div class="btn_application m_top">
|
||||||
<a type="button" class="common_btn_type_1 gray btn_cancel"><span>취소</span></a>
|
<a type="button" class="common_btn_type_1 gray btn_cancel"><span>취소</span></a>
|
||||||
<div class="btn_gap"></div>
|
<!-- <div class="btn_gap"></div>-->
|
||||||
<button type="button" class="common_btn_type_1 btn_complete" disabled><span>인증 완료</span></button>
|
<!-- <button type="button" class="common_btn_type_1 btn_complete" disabled><span>인증 완료</span></button>-->
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <!– 탭 메뉴 –>-->
|
|
||||||
<!-- <div class="tab-wrap">-->
|
|
||||||
<!-- <div class="tabs">-->
|
|
||||||
<!-- <ul class="tab_nav tabm">-->
|
|
||||||
<!-- <li class="active"><a href="#tab1">이메일 인증</a></li>-->
|
|
||||||
<!-- </ul>-->
|
|
||||||
|
|
||||||
<!-- <!– 이메일 인증 폼 –>-->
|
|
||||||
<!-- <div class="tab active" id="tab1">-->
|
|
||||||
<!-- -->
|
|
||||||
<!-- </div>-->
|
|
||||||
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user