Spring Security) UserDetailsService에서 비밀번호는 어디에서 검사하는 걸까?

Dokuny·2022년 1월 12일
5

Spring Security

목록 보기
6/7

스프링 시큐리티 form login을 구현하다가 문득 든 의문인데 UserDetailsService에서 loadUserByUsername(String username)에서는 아이디로만 DB에서 조회하고 사용자 정보를 반환해주기만 하지 비밀번호를 검증하는 것은 전혀 보이지 않는다.

그렇다면 어디서 비밀번호를 검증해서 로그인이 잘되도록 해주는 것일까?

나와같은 의문을 가진 사람이 있어서 이걸 참고해서 코드 까보면서 찾아봤다.

위의 링크를 보면(위의 링크 코드를 퍼왔다)

 String presentedPassword = authentication.getCredentials().toString();

		if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
			logger.debug("Authentication failed: password does not match stored value");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}

비밀번호 체크는 DaoAuthenticationProvider 라는 곳에서 대신 처리를 해주는데, passwordEncoder.matches() 를 통해서 처리를 해주고 있는 것을 볼 수 있다.
또한 PasswordEncoderDaoAuthenticationProvider에 필드로 들어있는 것을 확인할 수 있다(이건 직접 코드를 까보자)

그렇다면 저 인코더는 어떻게 설정해둔 것일까?

보통 시큐리티 설정은 WebSecurityConfigurerAdapter를 상속한 Config 클래스를 만들어서 사용하는데, 부모 클래스의 메소드 중 protected void configure(AuthenticationManagerBuilder auth)를 아래와 같이 오버라이드하여 사용한 게 포인트였다.

@Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.userDetailsService(principalDetailsService).passwordEncoder(passwordEncoder());
   }

AuthenticationManagerBuilder 를 통해 userDetailsService를 설정해두고 거기에 passwordEncoder에 내가 사용한 인코더를 매개변수로 넣어두면

AbstracDaoAuthenticationConfigurer라는 추상클래스가 DaoAuthenticationProvider의 passwordEncoder를 set 해준다.

public C passwordEncoder(PasswordEncoder passwordEncoder) {
	this.provider.setPasswordEncoder(passwordEncoder);
	return (C) this;
}

그 후 DaoAuthenticationProvider가 받은 PasswordEncoder로 비밀번호를 대조해주던 것!

찾아보니 DaoAuthenticationProvider를 사용하는 것 말고 AuthenticationProvider 인터페이스를 구현해서 커스터마이징하여 사용하는 것도 가능한 것 같다.

profile
모든 것은 직접 경험해보고 테스트하자

1개의 댓글

comment-user-thumbnail
2022년 11월 29일

궁금했던 점 완전히 해결하고 갑니다 감사해요 🙏

답글 달기