diff --git a/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java index 8b5ec11064..b628ef0234 100644 --- a/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java @@ -99,12 +99,45 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication /** * Sets the PasswordEncoder instance to be used to encode and validate passwords. - * If not set, {@link PlaintextPasswordEncoder} will be used by default. + * If not set, the password will be compared as plain text. + *

+ * For systems which are already using salted password which are encoded with a previous release, the encoder + * should be of type {@code org.springframework.security.authentication.encoding.PasswordEncoder}. Otherwise, + * the recommended approach is to use {@code org.springframework.security.crypto.password.PasswordEncoder}. * - * @param passwordEncoder The passwordEncoder to use + * @param passwordEncoder must be an instance of one of the {@code PasswordEncoder} types. */ - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; + public void setPasswordEncoder(Object passwordEncoder) { + Assert.notNull(passwordEncoder, "passwordEncoder cannot be null"); + + if (passwordEncoder instanceof PasswordEncoder) { + this.passwordEncoder = (PasswordEncoder) passwordEncoder; + return; + } + + if (passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) { + final org.springframework.security.crypto.password.PasswordEncoder delegate = + (org.springframework.security.crypto.password.PasswordEncoder)passwordEncoder; + this.passwordEncoder = new PasswordEncoder() { + public String encodePassword(String rawPass, Object salt) { + checkSalt(salt); + return delegate.encode(rawPass); + } + + public boolean isPasswordValid(String encPass, String rawPass, Object salt) { + checkSalt(salt); + return delegate.matches(rawPass, encPass); + } + + private void checkSalt(Object salt) { + Assert.isNull(salt, "Salt value must be null when used with crypto module PasswordEncoder"); + } + }; + + return; + } + + throw new IllegalArgumentException("passwordEncoder must be a PasswordEncoder instance"); } protected PasswordEncoder getPasswordEncoder() { @@ -115,6 +148,10 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication * The source of salts to use when decoding passwords. null * is a valid value, meaning the DaoAuthenticationProvider * will present null to the relevant PasswordEncoder. + *

+ * Instead, it is recommended that you use an encoder which uses a random salt and combines it with + * the password field. This is the default approach taken in the + * {@code org.springframework.security.crypto.password} package. * * @param saltSource to use when attempting to decode passwords via the PasswordEncoder */