Spring Security:password encoding in DB and in applicationContext

sergionni picture sergionni · Dec 15, 2011 · Viewed 61.3k times · Source

Have config (applicationContext-security.xml):

<authentication-manager alias="authenticationManager">
    <authentication-provider>
    <password-encoder hash="sha"/>
        <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>
</authentication-manager>

from other side have SQLs from my dataSource(it's JdbcDaoImpl):

...
    public static final String DEF_USERS_BY_USERNAME_QUERY =
            "select username,password,enabled " +
            "from users " +
            "where username = ?";
...

There is now word about sha in this code,so password selected from standard Spring Security users table not encoded.

Perhaps, I should provide some sha attribute for password column in my hibernate mapping config here:

<class name="model.UserDetails" table="users">
    <id name="id">
        <generator class="increment"/>
    </id>
    <property name="username" column="username"/>
    <property name="password" column="password"/>
    <property name="enabled" column="enabled"/>
    <property name="mail" column="mail"/>
    <property name="city" column="city"/>
    <property name="confirmed" column="confirmed"/>
    <property name="confirmationCode" column="confirmation_code"/>

    <set name="authorities" cascade="all" inverse="true">
        <key column="id" not-null="true"/>
        <one-to-many class="model.Authority"/>
    </set>

</class>

For now password saved to DB as is,but should be encoded.

How to friend applicationContext config and DB queries to be the same password encoding?

Answer

Shaun the Sheep picture Shaun the Sheep · Dec 16, 2011

If you are choosing a hashing system yourself, rather than building an app using an existing database which already contains hashed passwords, then you should make sure your hashing algorithm also uses a salt. Don't just use a plain digest.

A good choice is bcrypt, which we now support directly in Spring Security 3.1 via the BCryptPasswordEncoder (implemented using jBCrypt). This automatically generates a salt and concatenates it with the hash value in a single String.

Some databases have built-in support for hashing (e.g. Postgres). Otherwise, you need to hash the password yourself before passing it to JDBC:

String password = "plaintextPassword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);

That's all you need to do to encode the passwords when you create a user.

For authentication, you would use something like:

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

<bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <property name="userDetailsService" ref="yourJdbcUserService" />
  <property name="passwordEncoder" ref="encoder" />
</bean>