77 lines
3.0 KiB
Java
77 lines
3.0 KiB
Java
package com.kamco.cd.kamcoback.auth;
|
|
|
|
import com.kamco.cd.kamcoback.common.enums.StatusType;
|
|
import com.kamco.cd.kamcoback.common.enums.error.AuthErrorCode;
|
|
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
|
|
import com.kamco.cd.kamcoback.common.utils.HeaderUtil;
|
|
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
|
|
import com.kamco.cd.kamcoback.postgres.repository.members.MembersRepository;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.mindrot.jbcrypt.BCrypt;
|
|
import org.springframework.security.authentication.AuthenticationProvider;
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.security.core.AuthenticationException;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
@Component
|
|
@RequiredArgsConstructor
|
|
public class CustomAuthenticationProvider implements AuthenticationProvider {
|
|
|
|
private final MembersRepository membersRepository;
|
|
ServletRequestAttributes attr =
|
|
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
|
|
@Override
|
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
|
String username = authentication.getName();
|
|
String rawPassword = authentication.getCredentials().toString();
|
|
|
|
// 유저 조회
|
|
MemberEntity member =
|
|
membersRepository
|
|
.findByEmployeeNo(username)
|
|
.orElseThrow(() -> new CustomApiException(AuthErrorCode.LOGIN_ID_NOT_FOUND));
|
|
|
|
// 미사용 상태
|
|
if (member.getStatus().equals(StatusType.INACTIVE.getId())) {
|
|
throw new CustomApiException(AuthErrorCode.INACTIVE_ID);
|
|
}
|
|
|
|
// jBCrypt + 커스텀 salt 로 저장된 패스워드 비교
|
|
if (!BCrypt.checkpw(rawPassword, member.getPassword())) {
|
|
// 실패 카운트 저장
|
|
int cnt = member.getLoginFailCount() + 1;
|
|
member.setLoginFailCount(cnt);
|
|
membersRepository.save(member);
|
|
throw new CustomApiException(AuthErrorCode.LOGIN_PASSWORD_MISMATCH);
|
|
}
|
|
|
|
// 로그인 실패 체크
|
|
if (member.getLoginFailCount() >= 5) {
|
|
throw new CustomApiException(AuthErrorCode.LOGIN_PASSWORD_EXCEEDED);
|
|
}
|
|
|
|
// 인증 성공 → UserDetails 생성
|
|
CustomUserDetails userDetails = new CustomUserDetails(member);
|
|
|
|
// front에서 전달한 사용자 ip 등록
|
|
HttpServletRequest req = (attr != null) ? attr.getRequest() : null;
|
|
String ip = (req != null) ? HeaderUtil.get(req, "X-Forwarded-For") : null;
|
|
|
|
UsernamePasswordAuthenticationToken token =
|
|
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
|
|
|
token.setDetails(ip);
|
|
return token;
|
|
}
|
|
|
|
@Override
|
|
public boolean supports(Class<?> authentication) {
|
|
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
|
|
}
|
|
}
|