Spring Security

UserDetailsService 구현은 항상 요구되는 것인가?

iksadnorth 2023. 9. 1. 20:16

👣 개요

나의 의문점은 UserDetailsService와 UserDetails 인터페이스는
모든 AuthenticationProvider에서 요구하냐는 것이었다.
때문에 관련 질문을 ChatGPT에게 물어봤다.

물론 답변은 이렇게 나왔으나 ChatGPT는 자신이 모르는 정보라도
아는 것 마냥 거짓말을 하는 경우가 자주 발생하기 때문에 
해당 사실을 파악하기 위해 직접 코드를 확인하기로 했다.

 

👣 AuthenticationProvider 구현체들 코드 분석

우선 AuthenticationProvider 구현체들의 목록은 다음과 같다.

모든 클래스를 전수 조사하는 것은 쉽지 않기에 대표적인 몇몇 클래스로 확인하고자 했다.

  • AbstractUserDetailsAuthenticationProvider
  • AbstractJaasAuthenticationProvider
  • AnonymousAuthenticationProvider
  • DaoAuthenticationProvider
  • DefaultJaasAuthenticationProvider
  • JaasAuthenticationProvider
  • NullAuthenticationProvider
  • OAuth2LoginBeanDefinitionParser
  • PreAuthenticatedAuthenticationProvider
  • RememberMeAuthenticationProvider
  • TestingAuthenticationProvider

뭐.. 대부분의 소스 코드를 살펴본 결과 다음 구현체만 UserDetails 인터페이스를 사용하고 있었다.

  • AbstractUserDetailsAuthenticationProvider
  • PreAuthenticatedAuthenticationProvider
  • DaoAuthenticationProvider

 

👣 DaoAuthenticationProvider 분석

DaoAuthenticationProvider는 어차피 AbstractUserDetailsAuthenticationProvider의 구현체라서 
동일한 것으로 보면 되는데 해당 클래스가 보통 사용하게 되는 AuthenticationProvider라고 생각했다.
왜냐 하면 해당 클래스에서만 UserDetails와 UserDetailsService를 사용하고 있기 때문이다.

해당 클래스는 DB에서 로드한 결과를 토대로 인증 여부를 확인하는 코드를 가지고 있었다.
특히나 해당 클래스의 supports 메서드를 살펴보면
다음과 같이 UsernamePasswordAuthenticationToken 타입의
Authentication 객체만 지원하는 것으로 적혀있다.

supports 메서드는 AuthenticationManager가 다수의 AuthenticationProvider 중
적절한 AuthenticationProvider 1개를 고르는 기준이 되는 메서드다.
미리 구비된 수많은 AuthenticationProvider 중 Authentication 객체에
알맞는 AuthenticationProvider를 찾는 역할을 수행한다고 보면 된다.

결론적으로 해당 AuthenticationProvider는 UserDetails와 UserDetailsService를 사용한다.

 

👣 PreAuthenticatedAuthenticationProvider 분석

PreAuthenticatedAuthenticationProvider도 마찬가지로 UserDetails를 이용하는 AuthenticationProvider 다.
다만 해당 AuthenticationProvider는 UserDetailsService가 아닌
AuthenticationUserDetailsService라는 인터페이스를 요구할 뿐이다.
AuthenticationUserDetailsService는 UserDetailsService와 달리 loadUserDetails에서 String username을 파라미터로 받는 것이 아닌 Token을 받을 뿐이다. 이 때, To
ken은 Authentication를 상속받은 클래스여야 한다.

결론적으로 UserDetailsService를 요구하는 AuthenticationProvider는 
DaoAuthenticationProvider 밖에 없다고 생각하면 된다.

👣 결론 

항상 요구하는 것은 아니다.
DaoAuthenticationProvider만 UserDetailsService를 요구한다고 볼 수 있다.