'Spring security with password encoding and salting

I am trying to to authenticate user with spring-security with SHA hashing and salting. I have added extra field in users table for extra salt and customize UserDetails with this salt but whenever I try to login it is throwing bad credential exception.

My CustomJdbcDaoImpl class is :

public class CustomJdbcDaoImpl extends JdbcDaoImpl implements IChangePassword {

    private Logger logger = LoggerFactory.getLogger(CustomJdbcDaoImpl.class);
    

    @Override
    protected UserDetails createUserDetails(String username,UserDetails userFromUserQuery,
            List<GrantedAuthority> combinedAuthorities){
        String returnUsername = userFromUserQuery.getUsername();
        if(!isUsernameBasedPrimaryKey()){
            returnUsername = username;
        }
        logger.info("inside @class CustomJdbcDaoImpl @method createUserDetails USER DETAILS ARE: "+userFromUserQuery.getPassword()+"authritieds: "+combinedAuthorities);
        return new SaltedUser(returnUsername, 
                userFromUserQuery.getPassword(),
                userFromUserQuery.isEnabled(), 
                true,
                true, 
                true, 
                combinedAuthorities,
                ((SaltedUser)userFromUserQuery).getSalt());
         

    }

    @Override
    protected List<UserDetails> loadUsersByUsername(String username) {
        return getJdbcTemplate()
                .query(getUsersByUsernameQuery(), 
                        new String[] {username}, 
                        new RowMapper<UserDetails>() {
                    public SaltedUser mapRow(ResultSet rs, int rowNum) throws SQLException {
                        String username = rs.getString(1);
                        String password = rs.getString(2);
                        boolean enabled = rs.getBoolean(3);
                        String salt = rs.getString(4);
                        SaltedUser saltedUser = new SaltedUser(username, password, enabled,
                                true, 
                                true,
                                true,
                                AuthorityUtils.NO_AUTHORITIES, 
                                salt);
                        logger.info("inside @class @method loadUsersByUsername salted password  is: "+saltedUser.getPassword());
                        return saltedUser;
                    }
                    

                });
    }

    @Override
    public void changePassword(String username, String password) {
        getJdbcTemplate().
        update("update users set password = ? where username = ?",password,username);
        
    }

}

for changing password each time with salt my DatabasePasswordSecurerBean class is

public class DatabasePasswordSecurerBean extends JdbcDaoSupport {
    
        @Autowired
        private  PasswordEncoder passwordEncoder;
        
        @Autowired
        private SaltSource saltSource;
            
        @Autowired
        private UserDetailsService userDetailsService;
        
        private Logger logger = LoggerFactory.getLogger(DatabasePasswordSecurerBean.class);
        
        public void secureDatabase(){
            logger.info("inside @class DatabasePasswordSecurerBean  @method secureDatabase entry...");
            getJdbcTemplate().query("select username,password from users",new RowCallbackHandler(){
    
                @Override
                public void processRow(ResultSet rs) throws SQLException {
                   String username = rs.getString(1);
                   String password = rs.getString(2);
                   
                   UserDetails user = userDetailsService.loadUserByUsername(username);
                   String encodedPassword = passwordEncoder.encodePassword(password,saltSource.getSalt(user));
                   getJdbcTemplate().update("update users set password = ? where username = ?",
                          encodedPassword,username);
                  
                 logger.info("@class DatabasePasswordSecurerBean  @method secureDatabase updating password for user: "+username + "to: "+encodedPassword);
                }
                  
                
            });
            
        }
        
    }

 security.xml configurations are 

    
   

     <http auto-config="true">
          <intercept-url pattern="/*" access="ROLE_USER" />
        </http>
        
        <authentication-manager alias="authenticationManager">
                <authentication-provider user-service-ref="jdbcUserService">
                  <password-encoder ref="passwordEncoder" >
                    <salt-source ref="saltSource" />
                  </password-encoder>
                  
                  
                  
                </authentication-provider>
        </authentication-manager>
        
            
        </beans:beans>
    
     

and my application.xml is

<!-- Simple implementation of the standard JDBC DataSource interface,
                configuring the plain old JDBC DriverManager via bean properties -->
           <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="${db.driverClassName}" />
              <property name="url" value="${db.connection.url}" />
              <property name="username" value="${db.connection.username}" />
              <property name="password" value="${db.connection.password}" />
           </bean>
                                                                                 
           <bean id="jdbcUserService" class="com.petCart.springsecurity.security.CustomJdbcDaoImpl">
              <property name="dataSource" ref="dataSource" />
              <property name="enableGroups" value="true"></property>
              <property name="enableAuthorities" value="false"></property>
              <property name="usersByUsernameQuery">
                    <value>
                       select username,password,enabled,salt from users where username = ?
                    </value>
              </property>
              <property name="groupAuthoritiesByUsernameQuery">
                    <value>
                       select r.roleid,r.role_name,p.permissionname from roles r
                       join userrole ur on ur.roleid = r.roleid
                       join users u on u.id = ur.userid 
                       join rolepermission rp on r.roleid = rp.roleid 
                       join permissions p on p.permissionid = rp.permissionid
                       where u.username = ?
                    </value>
              </property>
          </bean>
          
          <!-- password encoder -->
           <bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder"/>
           <bean class="com.petCart.springsecurity.security.DatabasePasswordSecurerBean"  init-method="secureDatabase" depends-on="dataSource">
                <property name="dataSource" ref="dataSource" />
           </bean>
           <bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
               <property name="userPropertyToUse" value="username" />
           </bean>
    
       


Solution 1:[1]

Try to change from

<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
   <property name="userPropertyToUse" value="username" />
</bean>

to

<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
   <property name="userPropertyToUse" value="salt" />
</bean>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user2669657