에러 메시지
There is no PasswordEncoder mapped for the id "null"
Spring Security를 이용해 로그인 기능을 구현하는 과정에서 발생한 에러.
- MainTestApplication -
@SpringBootApplication
public class MainTestApplication {
@Bean
public PasswordEncoder passwordEncoder(){return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
public static void main(String[] args) {
SpringApplication.run(MainTestApplication.class, args);
System.out.println("program start");
}
}
- LoginService -
// 1. Login ID/PW 를 기반으로 Authentication 객체 생성
// 이때 authentication 는 인증 여부를 확인하는 authenticated 값이 false
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(req.getLoginId(), req.getPassword());
// 2. 실제 검증 (사용자 비밀번호 체크)이 이루어지는 부분
// authenticate 매서드가 실행될 때 CustomUserDetailsService 에서 만든 loadUserByUsername 메서드가 실행
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
// 3. 인증 정보를 기반으로 JWT 토큰 생성
String tokenInfo = createToken(req);
다른 설정때문에 생긴 에러가 아니었으므로 이외의 Spring Security설정은 생략.
위처럼 PasswordEncoder
Bean객체를 main클래스에 선언한 후 실행 시 에러가 발생했다.
password가 암호화되지 않았거나, 인코딩 종류를 지정하지 않았을 때 발생하는 에러로,
내 경우 인코딩 종류를 지정하지 않아 발생한 것이었다.
PasswordEncoder
는 기본적으로 여러가지 인코딩 방식을 제공한다.
PasswordEncoder
를 이용하여 암호화 시 결과에 인코딩 방식까지 포함되어 출력되는데, 이를 제외하고 암호화 된 문자열만 DB에 저장 시 어떤 인코딩을 적용해야할지 알 수 없어 에러가 발생하게 된다.
아래의 두 가지 방법 중 원하는 방법을 선택하면 된다.
PasswordEncoder
를 BCryptPasswordEncoder
로 변경하다.PasswordEncoder
Bean생성 시 객체를 BCryptPasswordEncoder
로 생성해버리면 인코딩을 BCrypt
방식으로 고정하여 적용한다.
// @Bean
// public PasswordEncoder passwordEncoder(){return PasswordEncoderFactories.createDelegatingPasswordEncoder();
// }
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
PasswordEncoder
를 BCrypt
로 변경하는 등 인코딩 방식을 고정하지 않으려면 DB에 password 저장 시 {bcrypt}$2a$10$m8Fx0hgob1HbiFeIJZjFr.6MytbMA9TruF/xgnKytf9OXU63nx4nq
와 같이 인코딩 종류를 함께 저장한다.
참고로 $2a$10$m8Fx0hgob1HbiFeIJZjFr.6MytbMA9TruF/xgnKytf9OXU63nx4nq
처럼 인코딩 완료된 값만 저장하면 오류가 발생한다.