개발/일지
[Error - SpringSecurity] java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
Zziny
2023. 2. 20. 04:05
SpringSecurity를 적용하기위해서,
USER 테이블에 ID : test, PASSWORD : 1234 저장하고 로그인을 시도하였더니, 해당 error가 발생하였다.
원인
SpringSecurity가 로그인 과정에서 어떤 Encoder를 쓸지는 database에 저장된 password의 prefix { Encoder명 }를 보고 결정 하는데 db에 저장할 때 password를 encode하지 않고 저장함.
-> SpringSecurity가 prefix를 보고 Enocder형식을 정해야 하는데, prefix가 설정 되어 있지 않아서 에러가 난 것
해결
PasswordEncoderFactories.createDelegatingPasswordEncoder() 사용
-> createDelegatingPasswordEncoder() 메서드 들어가 보면
-> 기본으로 BCryptPasswordEncoder 사용하는 것을 알 수 있음
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder(); // PasswordEncode로 BCryptPasswordEncoder 사용
}
public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256",
new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
회원가입 시 password를 encode해서 DB에 저장했다.
import com.numble.bankingserver.user.domain.User;
import com.numble.bankingserver.user.dto.JoinDTO;
import com.numble.bankingserver.user.repository.UserRepository;
import javax.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@Transactional
public class UserService {
private final UserRepository repository;
private final PasswordEncoder passwordEncoder;
public void joinUser(JoinDTO joinDTO) throws Exception {
if (repository.findByUserId(joinDTO.getId()).isPresent()) {
throw new Exception("이미 존재하는 아이디입니다.");
}
User user = User.createUser(joinDTO);
user.passwordEncode(passwordEncoder);
repository.save(user);
}
}