Guy Korland
Guy Korland

Reputation: 9568

BadCredentialsException when migrating from Spring 3.0.x to 3.1.x

We have migrated from 3.0.7 spring security to 3.1.2, and one of our tests that uses in-memory-config fails on bad credentials.

We don't do anything special, just authenticate one of the users with plain text username and password. once authenticated, we populate our authorities.

Code:

public Authentication authenticate(UserDetails userDetails)
        throws AuthenticationException {
    try {
        org.springframework.security.core.Authentication authenticate = authenticationManager.authenticate(createAuthenticationRequest(userDetails));
        if (!authenticate.isAuthenticated()) {
            throw new AuthenticationException("Authentication failed for user ["+userDetails.getUsername()+"]");
        }

        Collection<? extends GrantedAuthority> grantedAuthorities = authenticate.getAuthorities();
                    ...
             } catch(Exception exception) {
        throw new AuthenticationException(exception);
    }

Code:

<bean id="daoAuthenticationProvider" 
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="daoUserDetailsService" />
</bean>

<bean id="daoUserDetailsService" class="org.springframework.security.core.userdetails.memory.InMemoryDaoImpl">
    <property name="userMap">
        <value>
            Edward = koala, READ_ONLY
        </value>
    </property>
</bean>

We get the following exception on a call to authenticate:

Caused by: org.springframework.security.authentication.BadCre dentialsException: Bad credentials
at org.springframework.security.authentication.dao.Da oAuthenticationProvider.additionalAuthenticationCh ecks(DaoAuthenticationProvider.java:67)
at org.springframework.security.authentication.dao.Ab stractUserDetailsAuthenticationProvider.authentica te(AbstractUserDetailsAuthenticationProvider.java: 149)
at org.springframework.security.authentication.Provid erManager.authenticate(ProviderManager.java:156)
at org.openspaces.security.spring.SpringSecurityManag er.authenticate(SpringSecurityManager.java:117)
... 11 more

Any ideas how to workaround it or if there is a patch pending this issue?

Upvotes: 0

Views: 964

Answers (2)

Jimmi Changa
Jimmi Changa

Reputation: 31

The following answer is based on Guy Korland's comment (Aug 16 '12 at 20:40) where he did further debugging:

The default value for erase-credentials changed from 'false' to 'true' with Spring 3.1 onward, and this is why your password is null'ed out when it is pulled from the cache. It also explains why your test case passed prior to Spring 3.1. The class you are retrieving from the cache is UserDetails, and once Spring has authenticated the unencrypted password, it no longer has use for it so it erases it as a security measure. For your simple test scenario, you can override the erase-credentials value to 'false', but consider finding a more secure solution for the long term if you are indeed relying on that value unencrypted after authentication has been established.

Upvotes: 0

Shaun the Sheep
Shaun the Sheep

Reputation: 22762

Looking at your config, it might be a whitespace parsing issue, but it should be easy enough to debug by putting a breakpoint in DaoAuthenticationProvider.additionalAuthenticationChecks to see why the authentication fails.

In any case, the property editor approach for configuring in-memory users is deprecated in favour of namespace configuration. You can use something like

<security:user-service id="daoUserDetailsService">
    <security:user name="Edward" password="koala" authorities="READ_ONLY" />
</security:user-service>

to get the same result. And of course you have to add the security namespace to your application context file.

Upvotes: 2

Related Questions