Reputation: 9568
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
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
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