parent
6c69333df6
commit
4529e09339
|
@ -74,23 +74,6 @@ abstract class AbstractDaoAuthenticationConfigurer<B extends ProviderManagerBuil
|
|||
return (C) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying the
|
||||
* {@link org.springframework.security.authentication.encoding.PasswordEncoder} to use
|
||||
* with the {@link DaoAuthenticationProvider}. The default is to use plain text.
|
||||
*
|
||||
* @param passwordEncoder The
|
||||
* {@link org.springframework.security.authentication.encoding.PasswordEncoder} to
|
||||
* use.
|
||||
* @return the {@link SecurityConfigurer} for further customizations
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public C passwordEncoder(
|
||||
org.springframework.security.authentication.encoding.PasswordEncoder passwordEncoder) {
|
||||
provider.setPasswordEncoder(passwordEncoder);
|
||||
return (C) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(B builder) throws Exception {
|
||||
provider = postProcess(provider);
|
||||
|
|
|
@ -20,12 +20,12 @@ import org.springframework.security.authentication.AuthenticationProvider;
|
|||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|||
|
||||
/**
|
||||
* The plaintext password used to perform
|
||||
* {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is
|
||||
* PasswordEncoder#matches(CharSequence, String)} on when the user is
|
||||
* not found to avoid SEC-2056.
|
||||
*/
|
||||
private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
|
||||
|
@ -53,7 +53,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|||
|
||||
/**
|
||||
* The password used to perform
|
||||
* {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is
|
||||
* {@link PasswordEncoder#matches(CharSequence, String)} on when the user is
|
||||
* not found to avoid SEC-2056. This is necessary, because some
|
||||
* {@link PasswordEncoder} implementations will short circuit if the password is not
|
||||
* in a valid format.
|
||||
|
@ -91,8 +91,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|||
|
||||
String presentedPassword = authentication.getCredentials().toString();
|
||||
|
||||
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
|
||||
presentedPassword, salt)) {
|
||||
if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
|
||||
logger.debug("Authentication failed: password does not match stored value");
|
||||
|
||||
throw new BadCredentialsException(messages.getMessage(
|
||||
|
@ -116,8 +115,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|||
catch (UsernameNotFoundException notFound) {
|
||||
if (authentication.getCredentials() != null) {
|
||||
String presentedPassword = authentication.getCredentials().toString();
|
||||
passwordEncoder.isPasswordValid(userNotFoundEncodedPassword,
|
||||
presentedPassword, null);
|
||||
passwordEncoder.matches(presentedPassword, userNotFoundEncodedPassword);
|
||||
}
|
||||
throw notFound;
|
||||
}
|
||||
|
@ -146,45 +144,10 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|||
* @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
|
||||
* types.
|
||||
*/
|
||||
public void setPasswordEncoder(Object passwordEncoder) {
|
||||
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||
Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
|
||||
|
||||
if (passwordEncoder instanceof PasswordEncoder) {
|
||||
setPasswordEncoder((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;
|
||||
setPasswordEncoder(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");
|
||||
}
|
||||
|
||||
private void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||
Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
|
||||
|
||||
this.userNotFoundEncodedPassword = passwordEncoder.encodePassword(
|
||||
USER_NOT_FOUND_PASSWORD, null);
|
||||
this.userNotFoundEncodedPassword = passwordEncoder.encode(USER_NOT_FOUND_PASSWORD);
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.authentication.encoding;
|
||||
|
||||
/**
|
||||
* Interface for performing authentication operations on a password.
|
||||
*
|
||||
* @author colin sampaleanu
|
||||
* @deprecated It is recommended to use
|
||||
* {@link org.springframework.security.crypto.password.PasswordEncoder} instead which
|
||||
* better accommodates best practice of randomly generated salt that is included with the
|
||||
* password.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface PasswordEncoder {
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Encodes the specified raw password with an implementation specific algorithm.
|
||||
* </p>
|
||||
* <P>
|
||||
* This will generally be a one-way message digest such as MD5 or SHA, but may also be
|
||||
* a plaintext variant which does no encoding at all, but rather returns the same
|
||||
* password it was fed. The latter is useful to plug in when the original password
|
||||
* must be stored as-is.
|
||||
* </p>
|
||||
* <p>
|
||||
* The specified salt will potentially be used by the implementation to "salt" the
|
||||
* initial value before encoding. A salt is usually a user-specific value which is
|
||||
* added to the password before the digest is computed. This means that computation of
|
||||
* digests for common dictionary words will be different than those in the backend
|
||||
* store, because the dictionary word digests will not reflect the addition of the
|
||||
* salt. If a per-user salt is used (rather than a system-wide salt), it also means
|
||||
* users with the same password will have different digest encoded passwords in the
|
||||
* backend store.
|
||||
* </p>
|
||||
* <P>
|
||||
* If a salt value is provided, the same salt value must be use when calling the
|
||||
* {@link #isPasswordValid(String, String, Object)} method. Note that a specific
|
||||
* implementation may choose to ignore the salt value (via <code>null</code>), or
|
||||
* provide its own.
|
||||
* </p>
|
||||
*
|
||||
* @param rawPass the password to encode
|
||||
* @param salt optionally used by the implementation to "salt" the raw password before
|
||||
* encoding. A <code>null</code> value is legal.
|
||||
*
|
||||
* @return encoded password
|
||||
*/
|
||||
String encodePassword(String rawPass, Object salt);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Validates a specified "raw" password against an encoded password.
|
||||
* </p>
|
||||
* <P>
|
||||
* The encoded password should have previously been generated by
|
||||
* {@link #encodePassword(String, Object)}. This method will encode the
|
||||
* <code>rawPass</code> (using the optional <code>salt</code>), and then compared it
|
||||
* with the presented <code>encPass</code>.
|
||||
* </p>
|
||||
* <p>
|
||||
* For a discussion of salts, please refer to {@link #encodePassword(String, Object)}.
|
||||
* </p>
|
||||
*
|
||||
* @param encPass a pre-encoded password
|
||||
* @param rawPass a raw password to encode and compare against the pre-encoded
|
||||
* password
|
||||
* @param salt optionally used by the implementation to "salt" the raw password before
|
||||
* encoding. A <code>null</code> value is legal.
|
||||
*
|
||||
* @return true if the password is valid , false otherwise
|
||||
*/
|
||||
boolean isPasswordValid(String encPass, String rawPass, Object salt);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Password encoding implementations. Apart from the "null" implementations, they are all based on
|
||||
* password hashing using digest functions. See the
|
||||
* <a href="http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-services.html#core-services-password-encoding">
|
||||
* reference manual</a> for more information.
|
||||
* <p>
|
||||
* Third part implementations such as those provided by <a href="http://www.jasypt.org/springsecurity.html">Jasypt</a>
|
||||
* can also be used.
|
||||
*/
|
||||
package org.springframework.security.authentication.encoding;
|
||||
|
|
@ -390,9 +390,9 @@ public class DaoAuthenticationProviderTests {
|
|||
@Test
|
||||
public void testGettersSetters() {
|
||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||
provider.setPasswordEncoder(new PWE());
|
||||
provider.setPasswordEncoder(new BCryptPasswordEncoder());
|
||||
assertThat(provider.getPasswordEncoder().getClass()).isEqualTo(
|
||||
PWE.class);
|
||||
BCryptPasswordEncoder.class);
|
||||
|
||||
provider.setSaltSource(new SystemWideSaltSource());
|
||||
assertThat(provider.getSaltSource().getClass()).isEqualTo(
|
||||
|
@ -407,17 +407,6 @@ public class DaoAuthenticationProviderTests {
|
|||
assertThat(provider.isForcePrincipalAsString()).isTrue();
|
||||
}
|
||||
|
||||
static class PWE implements org.springframework.security.authentication.encoding.PasswordEncoder {
|
||||
@Override public String encodePassword(String rawPass, Object salt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public boolean isPasswordValid(String encPass, String rawPass,
|
||||
Object salt) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGoesBackToAuthenticationDaoToObtainLatestPasswordIfCachedPasswordSeemsIncorrect() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
|
||||
|
|
Loading…
Reference in New Issue