개인 프로젝트 중 JWT 인증방식을 사용하기 위해 인프런 Spring Boot JWT Tutorial 강의를 듣고 있습니다.
로그인 쿼리를 받아 아이디와 비밀번호가 맞을 경우 토큰을 돌려주는 지점인데, 생각해보니 이제껏 비밀번호를 대조하는 로직은 작성한 적이 없습니다. 그저 config에서 BcryptPasswordEncoder
를 빈으로 띄워놨을 뿐 어디에서도 match
같은 메서드를 사용한 적이 없는데 어떻게 비밀번호를 검사하는걸까요? 디버그 결과를 간단히 정리해봤습니다.
ProviderManager
에게 username, password를 Authentication형태로 넘겨줌ProviderManager
는 Authentication을 보고 적절한 provider를 찾아 authenticate
method를 호출. 이부분이 잘 이해가 안되는데 결과적으로 DaoAuthenticationProvider
가 authenticate
합니다.authenticationManagerBuilder.getObject().authenticate(authenticationToken);
authenticate
method 내 additionalAuthenticationChecks
method에서 비밀번호를 확인합니다. protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (authentication.getCredentials() == null) {
this.logger.debug("Failed to authenticate since no credentials provided");
throw new BadCredentialsException(this.messages
.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
String presentedPassword = authentication.getCredentials().toString();
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
this.logger.debug("Failed to authenticate since password does not match stored value");
throw new BadCredentialsException(this.messages
.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
}
추상화된 객체들이 복잡하게 서로 의존하고 있어 이정도 흐름만 파악하고 넘어가겠습니다.
인프런 - Spring Boot JWT Tutorial(정은구)
Github - Spring Security의 사용자 비밀번호 검사(HomoEfficio)