|
@@ -24,6 +24,7 @@ import org.springframework.security.providers.encoding.PasswordEncoder;
|
|
import org.springframework.security.providers.encoding.PlaintextPasswordEncoder;
|
|
import org.springframework.security.providers.encoding.PlaintextPasswordEncoder;
|
|
import org.springframework.security.userdetails.UserDetails;
|
|
import org.springframework.security.userdetails.UserDetails;
|
|
import org.springframework.security.userdetails.UserDetailsService;
|
|
import org.springframework.security.userdetails.UserDetailsService;
|
|
|
|
+import org.springframework.security.userdetails.UsernameNotFoundException;
|
|
import org.springframework.dao.DataAccessException;
|
|
import org.springframework.dao.DataAccessException;
|
|
import org.springframework.util.Assert;
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
@@ -35,10 +36,24 @@ import org.springframework.util.Assert;
|
|
* @version $Id$
|
|
* @version $Id$
|
|
*/
|
|
*/
|
|
public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
|
|
public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
|
|
|
|
+ //~ Static fields/initializers =====================================================================================
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The plaintext password used to perform {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is
|
|
|
|
+ * not found to avoid SEC-2056.
|
|
|
|
+ */
|
|
|
|
+ private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
|
|
|
|
|
|
//~ Instance fields ================================================================================================
|
|
//~ Instance fields ================================================================================================
|
|
|
|
|
|
- private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder();
|
|
|
|
|
|
+ private PasswordEncoder passwordEncoder;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The password used to perform {@link PasswordEncoder#isPasswordValid(String, String, Object)} 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.
|
|
|
|
+ */
|
|
|
|
+ private String userNotFoundEncodedPassword;
|
|
|
|
|
|
private SaltSource saltSource;
|
|
private SaltSource saltSource;
|
|
|
|
|
|
@@ -46,6 +61,10 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|
|
|
|
|
private boolean includeDetailsObject = true;
|
|
private boolean includeDetailsObject = true;
|
|
|
|
|
|
|
|
+ public DaoAuthenticationProvider() {
|
|
|
|
+ setPasswordEncoder(new PlaintextPasswordEncoder());
|
|
|
|
+ }
|
|
|
|
+
|
|
//~ Methods ========================================================================================================
|
|
//~ Methods ========================================================================================================
|
|
|
|
|
|
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
|
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
|
@@ -85,6 +104,13 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|
catch (DataAccessException repositoryProblem) {
|
|
catch (DataAccessException repositoryProblem) {
|
|
throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
|
throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
|
}
|
|
}
|
|
|
|
+ catch (UsernameNotFoundException notFound) {
|
|
|
|
+ if(authentication.getCredentials() != null) {
|
|
|
|
+ String presentedPassword = authentication.getCredentials().toString();
|
|
|
|
+ passwordEncoder.isPasswordValid(userNotFoundEncodedPassword, presentedPassword, null);
|
|
|
|
+ }
|
|
|
|
+ throw notFound;
|
|
|
|
+ }
|
|
|
|
|
|
if (loadedUser == null) {
|
|
if (loadedUser == null) {
|
|
throw new AuthenticationServiceException(
|
|
throw new AuthenticationServiceException(
|
|
@@ -100,6 +126,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|
* @param passwordEncoder The passwordEncoder to use
|
|
* @param passwordEncoder The passwordEncoder to use
|
|
*/
|
|
*/
|
|
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
|
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
|
|
|
+ this.userNotFoundEncodedPassword = passwordEncoder.encodePassword(USER_NOT_FOUND_PASSWORD, null);
|
|
this.passwordEncoder = passwordEncoder;
|
|
this.passwordEncoder = passwordEncoder;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -143,6 +170,6 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
|
*/
|
|
*/
|
|
public void setIncludeDetailsObject(boolean includeDetailsObject) {
|
|
public void setIncludeDetailsObject(boolean includeDetailsObject) {
|
|
this.includeDetailsObject = includeDetailsObject;
|
|
this.includeDetailsObject = includeDetailsObject;
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|