Spring Security 에서 인증(로그인)시에 예외가 발생할 수 있는데 이를 처리하는 과정을 정리해보고자 합니다.
📍 인증 과정에서 예외가 발생하는 이유
Spring Security 에서 로그인 요청이 들어오면 AuthenticationManager 가 인증을 시도합니다. 이 과정에서 적절한 AuthenticationProvider 를 선택하여 인증을 수행하는데, 아이디나 비밀번호가 잘못된 경우, 계정이 잠긴 경우 등 다양한 이유로 인증이 실패할 수 있습니다.
인증이 실패하면 AuthenticationException 이 발생합니다. SpringSecurity 는 이를 상속하는 다양한 예외 클래스를 제공하여, 실패 원인에 따라 다른 예외가 발생하도록 합니다.

📍인증 과정에서 예외가 발생하는 흐름
로그인 과정에서 예외가 발생하는 경로를 따라가보았습니다.
1️⃣ 로그인 요청을 받으면 AuthenticationManager 에게 인증을 위임하도록 하였습니다.
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(username, password)
);
AuthenticationManager 의 구현체는 ProviderManager 입니다.
2️⃣ AuthenticationManger 의 구현체인 ProviderManager 가 AuthenticationProvider 를 선택하여 인증을 진행합니다.
- ProviderManager 는 여러 개의 AuthenticationProvider 중 가장 적절한 Provider 를 선택하며, 기본적으로 DaoAuthenticationProvider 가 선택됩니다.
public class ProviderManager implements AuthenticationManager {
private List<AuthenticationProvider> providers;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
for (AuthenticationProvider provider : providers) {
if (provider.supports(authentication.getClass())) {
return provider.authenticate(authentication);
}
}
throw new AuthenticationException("인증 실패");
}
}
3️⃣ DaoAuthenticationProvider 가 사용자 정보를 조회하고 인증을 검증합니다.
- UserDetailsService를 이용하여 사용자 정보 조회
- 비밀번호 검증 후 불일치하면 BadCredentialsException 발생
- 사용자가 없으면 UsernameNotFoundException 발생
public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (!passwordEncoder.matches(authentication.getCredentials().toString(), userDetails.getPassword())) {
throw new BadCredentialsException("아이디 또는 비밀번호가 일치하지 않습니다.");
}
}
}
DaoAuthenticationProvider 는 AbstractUserDetailsAuthenticationProvider 를 상속받은 클래스입니다.

📍@ControllerAdvice 를 활용한 예외 처리
인증 과정에서 발생하는 예외를 한 곳에서 관리하고, 사용자가 이해할 수 있는 커스텀 응답(JSON) 형태로 변환하기 위해 @ControllerAdvice 를 활용하였습니다.


✅ 최종 정리
- Spring Security의 인증 과정
- AuthenticationManager → ProviderManager → DaoAuthenticationProvider
- 사용자가 로그인 요청을 하면, DaoAuthenticationProvider에서 비밀번호 검증
- 검증 실패 시 AuthenticationException 발생
- @ControllerAdvice 를 활용한 예외 처리
- @ExceptionHandler 를 이용해 인증 예외를 잡아서 커스텀 JSON 응답 반환
- 사용자가 쉽게 이해할 수 있도록 적절한 에러 메시지 제공
참고
'Server > Spring' 카테고리의 다른 글
[Spring] 로그를 어떻게 남겨야 할까? (0) | 2024.09.09 |
---|---|
[Spring/JPA] EntityListener 로 효율적인 이벤트 처리를 구현해보도록 하겠습니다. (1) | 2024.09.06 |
[Spring] 스프링 4.2 이후 version 에서 Application Event 도입을 해보았습니다. (0) | 2024.09.02 |
[Spring] failed to lazily initialize a collection of role (2) | 2024.08.14 |
[Spring/JPA] 엔티티 생명주기(Entity Lifecycle) 에 대해 알아보겠습니다. (0) | 2023.10.20 |