해결된 질문
작성
·
249
2
현재 저희가 만든 AuthenticationProvider 를 구현한 Custom
AuthenticationProvider에서
UserDetailsService 를 사용했을 뿐인데, 어떻게 CustomUserDetailsService가 호출이 되는지 궁금합니다.
저는 당연희 SecurityConfig에서 auth.userDetailsService의 매개변수로 CustomUserDetailsService를 넘겨줄 줄 알았는데
그냥 auth.authenticationProvider의 매개변수로 CustomAuthenticationProvider 만 넘겨줬을 뿐인데,
심지어 그 안에는 CustomUserDetailsService 를 사용한다는 디테일한 지시도 없을 뿐더러 인터페이스로만 정의 되어있는 UserServiceDetails를 사용할 뿐인데 어떻게 CustomUserDetailsService 가 호출되는지 궁금하네요.
또한 PasswordEncoder를 이용해서 password를 비교할 때 userDetailsService.loadUserByUsername 메소드에서 반환받은 AccountContext 객체의 getAccount().getPassword()랑 비교를 하는지 궁금합니다.
그냥 AccountContext 객체의 getPassword 하는 것이랑은 차이가 있는지요.
또 마지막으로 Config 클래스에서 auth.authenticationProvider 에 지정한 커스텀 클래스는 바로 ProviderManager 의 parent 필드에 지정되는건가요.
항상 좋은 강의 잘 듣고있습니다. 감사합니다.
답변 1
5
네
첫 번째 질문 답변입니다.
CustomAuthenticationProvider 에 있는 CustomUserDetailsService 는 의존성 주입니다.
비록 UserDetailsService userDetailsService 라고 했어도 스프링 컨테이너에 UserDetailsService 타입으로 생성된 빈이 CustomUserDetailsService 밖에 없을 경우 자동을 주입되게 됩니다.
만약 UserDetailsService 타입으로 생성된 빈이 두개 이상일 경우에는 말씀하신 것처럼
UserDetailsService customUserDetailsService 혹은 @Autowired 가 아닌 @Resource(name="customUserDetailsService") 라고 해야 합니다.
두 번째 질문 답변입니다.
AccountContext 객체의 getAccount().getPassword() 와 AccountContext 객체의 getPassword 의 차이는 없습니다.
다만 AccountContext 는 Entity 가 아닌 일반 도메인 객체이기 때문에 password 를 저장하는 것은 보안상 위험할 수 있습니다.
그래서 password 값을 필요에 의해 null 로 변경할 수 있기 때문에 Account 객체에서 참조한다고 보시면 될 것 같습니다.
그러나 이것도 꼭 그렇게 해야만 한다는 것은 아니니 용도에 맞게 처리하시면 됩니다.
세 번째 질문 답변입니다.
네
스프링 시큐리티는 초기화 시 시큐리티가 직접 제공하는 AuthenticationProvider 객체들, 가령 DaoAuthenticationProvider, RememberMeAuthenticationProvider 등을 먼저 기본 ProviderManager 의 providers 변수에 저장하고 사용자가 직접 정의한 CustomAuthenticationProvider 객체들은 부모 ProviderManager 에 저장을 하고 있습니다.
즉 기본적으로 제공하는 AuthenticationProvider 가 없을 경우 부모 ProviderManager 의 CustomAuthenticationProvder 객체들을 다시 탐색 하도록 설계한 것 같습니다.
물론 이 순서도 변경은 가능하나 기본 초기화 설정들을 건드려야 하는 부분이 있어서 가급적 기본 흐름대로 하시길 권해 드립니다.
감사합니다.
답변 정말 감사드립니다!