@ -18,6 +18,7 @@ package org.springframework.security.ldap.authentication;
@@ -18,6 +18,7 @@ package org.springframework.security.ldap.authentication;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
import org.springframework.ldap.NameNotFoundException ;
import org.springframework.ldap.NamingException ;
import org.springframework.ldap.core.DirContextOperations ;
import org.springframework.ldap.core.support.BaseLdapPathContextSource ;
import org.springframework.security.authentication.BadCredentialsException ;
@ -52,6 +53,7 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
@@ -52,6 +53,7 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
private PasswordEncoder passwordEncoder = new LdapShaPasswordEncoder ( ) ;
private String passwordAttributeName = "userPassword" ;
private boolean usePasswordAttrCompare = false ;
//~ Constructors ===================================================================================================
@ -95,15 +97,25 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
@@ -95,15 +97,25 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
user . getDn ( ) + "'" ) ;
}
String encodedPassword = passwordEncoder . encodePassword ( password , null ) ;
byte [ ] passwordBytes = Utf8 . encode ( encodedPassword ) ;
if ( ! ldapTemplate . compare ( user . getDn ( ) . toString ( ) , passwordAttributeName , passwordBytes ) ) {
throw new BadCredentialsException ( messages . getMessage ( "PasswordComparisonAuthenticator.badCredentials" ,
"Bad credentials" ) ) ;
if ( usePasswordAttrCompare & & isPasswordAttrCompare ( user , password ) ) {
return user ;
} else if ( isLdapPasswordCompare ( user , ldapTemplate , password ) ) {
return user ;
}
throw new BadCredentialsException ( messages . getMessage ( "PasswordComparisonAuthenticator.badCredentials" ,
"Bad credentials" ) ) ;
}
return user ;
private boolean isPasswordAttrCompare ( DirContextOperations user , String password ) {
Object passwordAttrValue = user . getObjectAttribute ( passwordAttributeName ) ;
return passwordEncoder . isPasswordValid ( new String ( ( byte [ ] ) passwordAttrValue ) , password , null ) ;
}
private boolean isLdapPasswordCompare ( DirContextOperations user ,
SpringSecurityLdapTemplate ldapTemplate , String password ) {
String encodedPassword = passwordEncoder . encodePassword ( password , null ) ;
byte [ ] passwordBytes = Utf8 . encode ( encodedPassword ) ;
return ldapTemplate . compare ( user . getDn ( ) . toString ( ) , passwordAttributeName , passwordBytes ) ;
}
public void setPasswordAttributeName ( String passwordAttribute ) {
@ -111,8 +123,40 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
@@ -111,8 +123,40 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
this . passwordAttributeName = passwordAttribute ;
}
public void setPasswordEncoder ( PasswordEncoder passwordEncoder ) {
private void setPasswordEncoder ( PasswordEncoder passwordEncoder ) {
Assert . notNull ( passwordEncoder , "passwordEncoder must not be null." ) ;
this . passwordEncoder = passwordEncoder ;
}
public void setPasswordEncoder ( Object passwordEncoder ) {
if ( passwordEncoder instanceof PasswordEncoder ) {
this . usePasswordAttrCompare = false ;
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" ) ;
}
} ) ;
this . usePasswordAttrCompare = true ;
return ;
}
throw new IllegalArgumentException ( "passwordEncoder must be a PasswordEncoder instance" ) ;
}
}