Summary
org.springframework.security.crypto.password.PasswordEncoderFactories is inflexible as it impose bcrypt as default encoder id for the created DelegatingPasswordEncoder
Actual Behavior
PasswordEncoderFactories is not customizable it has only one static method returning a PasswordEncoder instead DelegatingPasswordEncoder:
public static PasswordEncoder createDelegatingPasswordEncoder()
Expected Behavior
My proposal as I havent' fork your project to make a pull request
package org.mitre.security.crypto.password;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.LdapShaPasswordEncoder;
import org.springframework.security.crypto.password.Md4PasswordEncoder;
import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
/**
* A {@link DelegatingPasswordEncoder} factory with default mappings. Additional
* mappings may be added using {@link #register(String, PasswordEncoder)} and
* the encoding will be updated to conform with best practices. However, due to
* the nature of {@link DelegatingPasswordEncoder} the updates should not impact
* users. The mappings current are:
*
* <ul>
* <li>bcrypt - {@link BCryptPasswordEncoder} (Also used for encoding)</li>
* <li>ldap - {@link LdapShaPasswordEncoder}</li>
* <li>md4 - {@link Md4PasswordEncoder}</li>
* <li>md5 - {@code new MessageDigestPasswordEncoder("MD5")}</li>
* <li>noop - {@link NoOpPasswordEncoder}</li>
* <li>pbkdf2 - {@link Pbkdf2PasswordEncoder}</li>
* <li>scrypt - {@link SCryptPasswordEncoder}</li>
* <li>sha-1 - {@code new MessageDigestPasswordEncoder("SHA-1")}</li>
* <li>sha-256 - {@code new MessageDigestPasswordEncoder("SHA-256")}</li>
* <li>sha256 - {@link StandardPasswordEncoder}</li>
* <li>argon2 - {@link Argon2PasswordEncoder}</li>
* </ul>
*
* @author Rob Winch
* @author Hichem BOURADA
* @since 5.3
*/
public class DelegatingPasswordEncoderFactory {
private final Map<String, PasswordEncoder> encoders = new HashMap<>();
public DelegatingPasswordEncoderFactory() {
this.registerDefaultEncoders();
}
public DelegatingPasswordEncoderFactory(Map<String, PasswordEncoder> encoders) {
this.encoders.putAll(encoders);
}
public DelegatingPasswordEncoderFactory register(String name, PasswordEncoder encoder) {
this.encoders.put(Objects.requireNonNull(name), Objects.requireNonNull(encoder));
return this;
}
protected void registerDefaultEncoders() {
for (DefaultEncoders encoder : DefaultEncoders.values()) {
this.register(encoder.encoderName, encoder.encoder);
}
}
public DelegatingPasswordEncoder create(String encoderId) {
return new DelegatingPasswordEncoder(encoderId, new HashMap<>(encoders));
}
@SuppressWarnings("deprecation")
public enum DefaultEncoders {
BCRYPT("bcrypt", new BCryptPasswordEncoder()), //
LDAP("ldap", new LdapShaPasswordEncoder()), //
MD4("md4", new Md4PasswordEncoder()), //
MD5("md5", new MessageDigestPasswordEncoder("MD5")), //
NOOP("noop", NoOpPasswordEncoder.getInstance()), //
PBKDF2("pbkdf2", new Pbkdf2PasswordEncoder()), //
SCRYPT("scrypt", new SCryptPasswordEncoder()), //
SHA_1("sha-1", new MessageDigestPasswordEncoder("SHA-1")), //
SHA_256("sha-256", new MessageDigestPasswordEncoder("SHA-256")), //
SHA256("sha256", new StandardPasswordEncoder()), //
ARGON2("argon2", new Argon2PasswordEncoder());
public final String encoderName;
public final PasswordEncoder encoder;
DefaultEncoders(String encoderName, PasswordEncoder encoder) {
this.encoderName = encoderName;
this.encoder = encoder;
}
}
}
Configuration
Version
5.2
Sample
Comment From: eleftherias
Thanks for the report @hbourada.
This is a duplicate of gh-5939. You can check out that issue for a workaround.