Ron
Ron

Reputation: 47

Spring Security Password Authentication

need some help or direction using Spring's security 3.1.x.

I am storing an encrypted password in MySql database. Which password is defined as a varchar(60) column.

The first time running the web app, I generated the password with the following code snippet:

String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);

I then took the String encodedPassword and pasted into the database column. I kept the code in my authentication-manager (snippet follows), and logged encodedPassword to the server log.

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider user-service-ref="usersDAO"> 
        <security:password-encoder ref="encoder" />
    </security:authentication-provider>
</security:authentication-manager>

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

My problem is that authentication fails with exception: Bad credentials when BCryptPasswordEncoder.matches() runs. The stored password is not matching the generated hash from the form input. The same text password that was used in the initial hash generation was used.

Each time I re-run the login entering the same text, the logged encodedPassword is different. Debugging I can see where the entity is being returned from the database correctly, so I don't think that is an issue. The issue seems to me that I'm not doing/setting something correctly in order to generate the same hash each time the text password is entered.

EDIT: Adding usersDAO.

import org.springframework.security.core.userdetails.UserDetailsService;

public interface UsersDAO extends Dao<Users>, UserDetailsService 
{
    Users getByUsername(String username);   
}

EDIT: adding implementation.

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Repository("usersDAO")
public class UsersDAO_DB extends AbstractHibernateDao<Users> implements UsersDAO
{
final Logger log = LoggerFactory.getLogger(this.getClass());

@Override
public Users getByUsername(String username) 
{
    String p = "12345";
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String encodedPassword = passwordEncoder.encode(p);
    log.debug("HELLOZ  ---->  " + encodedPassword);

    notNull(username, "username can't be null");
    return (Users) getSession()
        .getNamedQuery("users.byUsername")
        .setParameter("username", username)
        .uniqueResult();
}

@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws     UsernameNotFoundException, DataAccessException {
    notNull(username, "username can't be null");
    Users users = getByUsername(username);
    if (users == null) {
        throw new UsernameNotFoundException("No user with username " +  username);
    }
    return users;
}


@Override
public void create(Users t)
{
    // TODO Auto-generated method stub
}

@Override
public void update(Users t)
{
    // TODO Auto-generated method stub

}

@Override
public void delete(Users t)
{
    // TODO Auto-generated method stub

}

}

Any ideas?

Upvotes: 1

Views: 11329

Answers (2)

Ron
Ron

Reputation: 47

This was a newbie error here following a couple of different tutorials.

In the bean I had defined my security encoder as a: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder

To generate a test cryptic password I used the following code:

String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);
log.debug("HELLOZ  ---->  " + encodedPassword);

which was mixing the org.springframework.security.crypto.password.PasswordEncoder and the org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder. See the above code defining passwordEncoder.

Once I changed it to:

String p = "12345";
BCryptPasswordEncoder pe= new BCryptPasswordEncoder();
String encPassword =pe.encode(p);
log.debug("HELLB  ---->  " + encPassword);

copied the output to my database and retested everything worked fine.

Upvotes: 2

Shaun the Sheep
Shaun the Sheep

Reputation: 22762

Each time I re-run the login entering the same text, the logged encodedPassword is different".

Where is that logging coming from? Spring Security won't log incoming passwords and if you are using BCrypt it shouldn't be re-encoding them from scratch anywhere.

It sounds like you may be re-encoding the submitted password yourself, possibly in your usersDAO which isn't shown.

If not, please post your complete configuration and the logging output you're talking about.

Upvotes: 1

Related Questions