[스프링부트 시큐리티 에러] UsernameNotFoundException 작동하지않음

jyleever·2022년 5월 14일
0

Helpring 에러 로그

목록 보기
3/12

사용자가 존재하지 않은 오류 실패

이전 SecurityBoard에서 사용자가 존재하지 않은 오류가 뜨지 않은 문제에 대해 DaoAuthenticationProvider을 등록하면서 setHideUserNotFoundExceptions(false)을 통해 해결했는데 이번 프로젝트에서는 갑자기 내부 시스템 에러가 터졌다.

로그인 에러 핸들러는 다음과 같이 설정했다.

  • CustomAuthFailureHandler
@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);
    }
}

0개의 댓글