이전 SecurityBoard에서 사용자가 존재하지 않은 오류가 뜨지 않은 문제에 대해 DaoAuthenticationProvider
을 등록하면서 setHideUserNotFoundExceptions(false)
을 통해 해결했는데 이번 프로젝트에서는 갑자기 내부 시스템 에러가 터졌다.
로그인 에러 핸들러는 다음과 같이 설정했다.
@Component
@Slf4j
public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
/**
* HttpServletRequest : Request 정보
* HttpServletResponse : Response에 대해 설정할 수 있는 변수
* AuthenticationException : 로그인 실패 시 예외에 대한 정보
*/
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
String errorMessage;
if(exception instanceof UsernameNotFoundException){
errorMessage = "존재하지 않는 계정입니다. 회원가입 후 로그인해주세요.";
} else if (exception instanceof BadCredentialsException) {
errorMessage = "아이디 또는 비밀번호가 맞지 않습니다. 다시 확인해주세요.";
} else if (exception instanceof InternalAuthenticationServiceException) {
errorMessage = "내부 시스템 문제로 로그인 요청을 처리할 수 없습니다. 관리자에게 문의하세요.";
} else if (exception instanceof AuthenticationCredentialsNotFoundException) {
errorMessage = "인증 요청이 거부되었습니다. 관리자에게 문의하세요.";
} else {
errorMessage = "알 수 없는 오류로 로그인 요청을 처리할 수 없습니다. 관리자에게 문의하세요.";
}
log.info("failureHandler : " + errorMessage);
errorMessage = URLEncoder.encode(errorMessage, "UTF-8"); /* 한글 인코딩 깨지는 문제 방지 */
setDefaultFailureUrl("/auth/login?error=true&exception=" + errorMessage);
super.onAuthenticationFailure(request, response, exception);
}
}
UsernameNotFoundException
에러가 터져야 하는데 계속 내부 실패 에러(InternalAuthenticationServiceException
)가 터졌다.어디가 문제인가 찾기 위해 username이 DB에 존재하는지 확인하고 존재하지 않으면 UsernameNotFoundException
에러가 터지도록 설계한 CustomUserDetailsService
을 살펴보았다.
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Member member = memberRepository.findByUsername(username).orElseThrow(() ->
new IllegalArgumentException("사용자가 존재하지 않습니다."));
/** 시큐리티 세션에 유저 정보 저장**/
return new UserAdapter(member);
}
}
문제는 Member member = memberRepository.findByUsername(username).orElseThrow(() -> new IllegalArgumentException("사용자가 존재하지 않습니다."));
이 부분이었다!
회원이 존재하지 않으면 UsernameNotFoundException
이 아니라 IllegalArgumentException
을 터지게끔 작성해놔서 InternalAuthenticationServiceException
이 터진 거였다~~~!!
꼼꼼하게 코딩하자,,
CustomUserDetailsService
@Service
@Slf4j
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {
private final MemberRepository memberRepository;
private final HttpSession session;
/** username이 DB에 존재하는지 확인 **/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Member member = memberRepository.findByUsername(username).orElseThrow(() ->
new UsernameNotFoundException("사용자가 존재하지 않습니다."));
/** 시큐리티 세션에 유저 정보 저장**/
return new UserAdapter(member);
}
}