Spring security cannot match password - java

I have following spring security configuration:
<authentication-manager alias="userAuthenticationManager">
<!-- <authentication-provider user-service-ref="userSecurityService"> -->
<authentication-provider>
<password-encoder ref="encoder" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select email,password,prop_was_moderated from terminal_user where email = ? and prop_confirm_terminal=true"
authorities-by-username-query="select email,user_role from terminal_user where email = ?" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="10" />
</beans:bean>
and following configuration class
#Configuration
public class Configiuration {
#Bean
BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
I create user password like this:
...
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
...
public void register(...){
...
user.setPassword(bCryptPasswordEncoder.encode(generatedPassword));
...
}
...
But when I try to loging I seemessage that auth failed.
What do I wrong?

Related

How to call bean with #Autowiring from app context in security context

After a research, I still dont found a solution for this problem.
My aim is to validate user in Custom Authentication Provider using database but the #Autowiring always throw Null Pointer Exception.
Here my code:
Custom Authentication Provider:
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Autowired
private Validator iValidate;
#Override
public Authentication authenticate(Authentication auth) throws AuthenticationException{
if (iValidate.userNameCheck(auth.getName()) != "00") {
auth=null;
}
return auth:
}
#Override
public boolean supports(Class<?> auth) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(auth));
}
}
Validator.java:
#Component
public class Validator implements IsamSvc {
private StopWatch sw = new StopWatch();
#Autowired
private JdbcTemplate jdbcTemplate;
#Override
public String userNameCheck(String mercid, String caller) {
/////validating code/////
}
}
Spring Security XML:
<global-method-security pre-post-annotations="enabled" />
<http pattern="/resources/**" security="none" />
<http auto-config="false" use-expressions="true" disable-url-rewriting="true" >
<session-management session-fixation-protection="newSession" session-authentication-error-url="/login.do?sessionalreadyexist">
<concurrency-control max-sessions="1" expired-url="/login.do?expired" error-if-maximum-exceeded="true" />
</session-management>
<intercept-url pattern="/clearcache" access="permitAll()" />
<intercept-url pattern="/login.do" access="permitAll()" />
<intercept-url pattern="/**" access="isFullyAuthenticated()" />
<logout logout-success-url="/login.do?logout" delete-cookies="JSESSIONID" invalidate-session="true" />
<access-denied-handler error-page="/403" />
<form-login login-page='/login.do' login-processing-url="/login" default-target-url="/main" always-use-default-target="true" authentication-failure-url="/login.do?error" username-parameter="username" password-parameter="password" authentication-details-source-ref="CustomAuthInfoSource" /> -->
</http>
<authentication-manager>
<authentication-provider ref="CustomAuthenticationProvider" />
</authentication-manager>
<beans:bean id="CustomAuthenticationProvider" class="xx.xxx.xxxx.xxxxx.CustomAuthenticationProvider" />
beans.xml:
<beans:bean id="iValidate" class="xx.xxx.xxxx.xxxxx.Validator" scope="prototype" />
/////// Other beans ////////
when i call #Autowired private Validator iValidate; in #Controller class, it work normally,but in CustomAuthenticationProvider, it will return null ...
Any Solution?
annotate the CustomAuthenticationProvider with #Component annotation

Spring security authentication fails

I am using Spring security version 3.1.4.RELEASE. When I try to login to the application I am getting an error. I have cross checked the credentials in DB. Even though the credentials are correct the system is not lettng me to login. Following the details of error and my configuration settings.
Getting following error while trying to login to the system:
web.security.auth.CustomUsernamePasswordAuthenticationFilter username is support
web.security.auth.CustomUsernamePasswordAuthenticationFilter password is [PROTECTED]
web.security.auth.CustomUsernamePasswordAuthenticationFilter authRequest is org.springframework.security.authentication.UsernamePasswordAuthenticationToken#4a159a52: Principal: support; Credentials: [PROTECTED]; Authenticated: false; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 204.238.52.177; SessionId: 9B49838B0DF4224E169EAF425C0AABE9; Not granted any authorities
web.security.auth.CustomUsernamePasswordAuthenticationFilter Authentication manager was com.sun.proxy.$Proxy476
System.out loadUserByUsername support enter
org.springframework.security.authentication.event.LoggerListener Authentication event AuthenticationFailureServiceExceptionEvent: support; details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 204.238.52.177; SessionId: 9B49838B0DF4224E169EAF425C0AABE9; exception: null
Here I am getting the exception as null!
Config:
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<beans:bean id="plaintextPasswordEncoder" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder" />
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="daoUserDetailsService" />
<beans:property name="passwordEncoder" ref="plaintextPasswordEncoder" />
</beans:bean>
<beans:bean id="daoUserDetailsService" class="web.security.auth.DAOUserDetailsService">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<beans:bean id="dataSource" class="web.security.auth.DAODataSource" />
<beans:bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<filter-chain-map request-matcher="ant">
<filter-chain pattern="/**" filters="channelProcessingFilter, SecurityContextPersistenceFilter, logoutFilter, authenticationFilter, anonymousAuthFilter, exceptionTranslationFilter, filterSecurityInterceptor" />
</filter-chain-map>
</beans:bean>
<beans:bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<beans:property name="channelDecisionManager" ref="channelDecisionManager"/>
<beans:property name="securityMetadataSource">
<filter-security-metadata-source request-matcher="ant">
<intercept-url pattern="/**" access="REQUIRES_SECURE_CHANNEL"/>
</filter-security-metadata-source>
</beans:property>
</beans:bean>
<beans:bean id="channelDecisionManager" class="org.springframework.security.web.access.channel.ChannelDecisionManagerImpl">
<beans:property name="channelProcessors">
<beans:list>
<beans:ref bean="secureChannelProcessor"/>
<beans:ref bean="insecureChannelProcessor"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="secureChannelProcessor" class="org.springframework.security.web.access.channel.SecureChannelProcessor" />
<beans:bean id="insecureChannelProcessor" class="org.springframework.security.web.access.channel.InsecureChannelProcessor" />
<beans:bean id="SecurityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
<beans:bean id="authenticationFilter" class="web.security.auth.CustomUsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>
<beans:property name="usernameParameter" value="username"/>
<beans:property name="passwordParameter" value="password"/>
</beans:bean>
<beans:bean id="anonymousAuthFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<beans:property name="key" value="foobar"/>
<beans:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</beans:bean>
<beans:bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<beans:property name="key" value="foobar"/>
</beans:bean>
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="securityMetadataSource">
<filter-security-metadata-source>
<intercept-url pattern="/LoginPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/LoginExpiredPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/wicket/bookmarkable/web.sec.pages.LoginExpiredPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/images/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/*.png" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/*.ico" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/wicket/resource/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED"/>
</filter-security-metadata-source>
</beans:property>
</beans:bean>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="ROLE_"/>
</beans:bean>
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="/" />
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:list>
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout"/>
</beans:bean>
<beans:bean id="forceCookieUseFilter" class="web.security.ForceCookieUseFilter">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<beans:property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</beans:bean>
<beans:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/LoginPage"/>
</beans:bean>
<beans:bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/accessDenied.htm"/>
</beans:bean>
<beans:bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener"/>
AuthenticationFilter class as follows:
public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private boolean postOnly = true;
public CustomUsernamePasswordAuthenticationFilter() {
super("/j_spring_security_check");
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
if(this.getAuthenticationManager()==null){
logger.info("Authentication manager is null.");
} else {
logger.info("Authentication manager was "+this.getAuthenticationManager().getClass().getName());
}
return this.getAuthenticationManager().authenticate(authRequest);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setUsernameParameter(String usernameParameter) {
this.usernameParameter = usernameParameter;
}
public void setPasswordParameter(String passwordParameter) {
this.passwordParameter = passwordParameter;
}
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return usernameParameter;
}
public final String getPasswordParameter() {
return passwordParameter;
}
}
UserDetails class as follows:
public class DAOUserDetailsService implements UserDetailsService {
private DataSource dataSource;
public void setDataSource(DAODataSource dataSource) {
this.dataSource = dataSource;
}
public DAOUserDetailsService () { }
public DAOUserDetailsService (DAODataSource dataSource) {
this.dataSource = dataSource;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
DataSource ds = dataSource;
PreparedStatement userStatement = null;
try {
Connection con = ds.getConnection();
String userQuery = "SELECT USER_ID, USER_PASSWORD, USER_ENABLED FROM USER WHERE USER_ID = ?";
userStatement = con.prepareStatement(userQuery);
userStatement.setString(0, username);
ResultSet userResults = userStatement.executeQuery();
if (userResults.next()) {
final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority(
"supervisor");
final SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority(
"user");
Collection<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(supervisorAuthority);
authorityList.add(userAuthority);
return new User(userResults.getString(0), userResults.getString(1), authorityList);
}
throw new UsernameNotFoundException(username);
} catch (SQLException e) {
throw new UsernameNotFoundException(e.toString());
}
finally {
if (userStatement != null) {
try {
userStatement.close();
} catch (SQLException e) {
throw new UsernameNotFoundException(e.toString());
}
}
}
}
}
Kindly provide some idea on the issue.
Thanks in advance.
You can create your implementation of LoggerListener for investigate more the causes.
public class LoggerListener implements ApplicationListener<AbstractAuthorizationEvent> {
private static final Log logger = LogFactory.getLog(LoggerListener.class);
public void onApplicationEvent(AbstractAuthorizationEvent event) {
//investigation code
}
}
I had a very similar problem and the cause was one ClassCastException in other part of code, one controller.
In your class DAOUserDetailsService:
...
return new User(userResults.getString(0), userResults.getString(1), new ArrayList<GrantedAuthority>());
...
you return UserDeatils with empty authorities. So your user is loged in but he has no roles (not authorised).
You have to add ROLE_ prefix to role while creating your GrantedAuthority. So you code should look like:
// For xxx
final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority(
"ROLE_xxx");
Alternative: You can clear default prefix in RoleVoter but IMO this is not a good choice because ROLE_ prefix actually helps RoleVoter to understand what remaning string is.
<bean id="roleVoter" class="org.springframework.security.vote.RoleVoter">
<property name="rolePrefix" value=""></property>
</bean>

Spring security with Java Config doesn´t work eraseCredentials method

With the following Java Config configuration for Spring Security 3.2.2 and Spring Framework 3.2.8, user passsword is deleted even when I use '.eraseCredentials(false)' and it's not available using authentication.getCredentials().
#Configuration
#EnableWebSecurity
#Order( 1 )
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean( name = "authenticationEntryPoint" )
public LoginUrlAuthenticationEntryPoint authenticationEntryPoint() {
return new XhrAwareAuthenticationEntryPoint( "/home?noAuthenticated=expired" );
}
#Bean( name = "acessDeniedHandler" )
public AccessDeniedHandler acessDeniedHandler() {
XhrAwareAccessDeniedHandlerImpl xhrAwareAccessDeniedHandler = new XhrAwareAccessDeniedHandlerImpl();
xhrAwareAccessDeniedHandler.setErrorPage( "/denied" );
return xhrAwareAccessDeniedHandler;
}
#Bean( name = "atlasAuthenticationSuccessHandler" )
public AtlasAuthenticationSuccessHandler atlasAuthenticationSuccessHandler() {
return new AtlasAuthenticationSuccessHandler( "/views/hub" );
}
#Bean( name = "atlasAuthenticationFailureHandler" )
public AtlasAuthenticationFailureHandler atlasAuthenticationFailureHandler() {
return new AtlasAuthenticationFailureHandler( "/home?loginError=error" );
}
#Bean( name = "atlasLogoutSuccessHandler" )
public AtlasLogoutSuccessHandler atlasLogoutSuccessHandler() {
AtlasLogoutSuccessHandler atlasLogoutSuccessHandler = new AtlasLogoutSuccessHandler();
atlasLogoutSuccessHandler.setDefaultTargetUrl( "/home?logoff=disconnect" );
return atlasLogoutSuccessHandler;
}
#Override
public void configure( WebSecurity web ) throws Exception {
web.ignoring().antMatchers( "/resources/**" );
}
#Override
protected void configure( HttpSecurity http ) throws Exception {
http.csrf().disable()
.httpBasic()
.authenticationEntryPoint( this.authenticationEntryPoint() )
.and()
.exceptionHandling()
.accessDeniedHandler( this.acessDeniedHandler() )
.and()
.formLogin()
.usernameParameter( "j_username" )
.passwordParameter( "j_password" )
.loginPage( "/home" )
.loginProcessingUrl( "/login" )
.failureHandler( this.atlasAuthenticationFailureHandler() )
.successHandler( this.atlasAuthenticationSuccessHandler() )
.permitAll()
.and()
.logout()
.logoutUrl( "/logout" )
.logoutSuccessHandler( this.atlasLogoutSuccessHandler() )
.invalidateHttpSession( true )
.permitAll()
.and()
.authorizeRequests()
.antMatchers(
ViewsConstants.VIEWS_URI + "/**",
RssController.RSS_URI + "/**",
ProxySolrController.SEARCH_URI + "/**" )
.authenticated()
.antMatchers( ConfigurationProperties.ADMIN_URI + "/**" ).hasAnyRole( Role.ADMIN )
.antMatchers( "/**" ).permitAll();
}
#Configuration
#Profile( "DES" )
public static class AuthenticacioInMemoryConfig {
#Autowired
public void configureGlobal( AuthenticationManagerBuilder auth ) throws Exception {
auth.eraseCredentials( false ).inMemoryAuthentication()
.withUser( "user" ).password( "atlas" ).authorities( "ROLE_USER" ).and()
.withUser( "admin" ).password( "atlas" ).authorities( "ROLE_ADMIN" );
}
}
#Configuration
#Profile( "PRO" )
#PropertySource( "file:${config.env}/config_env.properties" )
public static class AuthenticacionLdapConfig {
#Value( "${ldap.host}" )
private String host;
#Value( "${ldap.port}" )
private String port;
#Value( "${ldap.basedn}" )
private String baseDn;
#Value( "${ldap.userdn}" )
private String userDn;
#Value( "${ldap.passw}" )
private String password;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean( name = "contextSource" )
public DefaultSpringSecurityContextSource contextSource() {
DefaultSpringSecurityContextSource contextSource =
new DefaultSpringSecurityContextSource( "ldap://" + this.host + ":" + this.port );
contextSource.setUserDn( this.userDn );
contextSource.setPassword( this.password );
return contextSource;
}
#Bean( name = "userSearch" )
public FilterBasedLdapUserSearch userSearch() {
return new FilterBasedLdapUserSearch( this.baseDn, "(bsalias={0})", this.contextSource() );
}
#Bean( name = "ldapAuthenticator" )
public LdapAuthenticator ldapAuthenticator() {
BindAuthenticator authenticator = new BindAuthenticator( this.contextSource() );
authenticator.setUserSearch( this.userSearch() );
return authenticator;
}
#Bean( name = "atlasAuthoritiesPopulator" )
public AtlasAuthoritiesPopulator atlasAuthoritiesPopulator() {
return new AtlasAuthoritiesPopulator();
}
#Bean( name = "ldapAuthenticationProvider" )
public LdapAuthenticationProvider ldapAuthenticationProvider() {
return new LdapAuthenticationProvider( this.ldapAuthenticator(), this.atlasAuthoritiesPopulator() );
}
#Autowired
public void configureGlobal( AuthenticationManagerBuilder auth ) throws Exception {
auth.eraseCredentials( false ).authenticationProvider( this.ldapAuthenticationProvider() );
}
}
}
However, using the xml configuration for the same spring security and spring framework is running ok and the password is available.
<context:property-placeholder location="file:${config.env:}/config_env.properties" />
<global-method-security secured-annotations="enabled"/>
<beans:bean id="authenticationEntryPoint"
class="es.isban.atlas.views.web.core.authentication.XhrAwareAuthenticationEntryPoint">
<beans:constructor-arg name="loginFormUrl" value="/home?noAuthenticated=expired"/>
</beans:bean>
<beans:bean id="accessDeniedHandler"
class="es.isban.atlas.views.web.core.authentication.XhrAwareAccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/denied" />
</beans:bean>
<beans:bean id="atlasAuthenticationSuccessHandler"
class="es.isban.atlas.views.web.core.authentication.AtlasAuthenticationSuccessHandler">
<beans:constructor-arg name="defaultTargetUrl" value="/views/hub"/>
</beans:bean>
<beans:bean id="atlasAuthenticationFailureHandler"
class="es.isban.atlas.views.web.core.authentication.AtlasAuthenticationFailureHandler">
<beans:constructor-arg name="defaultFailureUrl" value="/home?loginError=error"/>
</beans:bean>
<beans:bean id="atlasLogoutSuccessHandler"
class="es.isban.atlas.views.web.core.authentication.AtlasLogoutSuccessHandler">
<beans:property name="defaultTargetUrl" value="/home?logoff=disconnect" />
</beans:bean>
<!-- This is where we configure Spring-Security -->
<http use-expressions="true"
entry-point-ref="authenticationEntryPoint">
<access-denied-handler ref="accessDeniedHandler" />
<intercept-url pattern="/*" access="permitAll()"/>
<intercept-url pattern="/views/**" access="isAuthenticated()" />
<intercept-url pattern="/rss/**" access="isAuthenticated()" />
<intercept-url pattern="/search/**" access="isAuthenticated()" />
<intercept-url pattern="/admin/**" access="hasAnyRole('ROLE_ADMIN')" />
<form-login login-page="/home"
login-processing-url="/login"
authentication-success-handler-ref="atlasAuthenticationSuccessHandler"
authentication-failure-handler-ref="atlasAuthenticationFailureHandler" />
<!-- authentication-failure-url="/home?loginError=error"
default-target-url="/views/hub" -->
<logout logout-url="/logout"
invalidate-session="true"
success-handler-ref="atlasLogoutSuccessHandler" />
<!-- logout-success-url="/home"
delete-cookies="true" -->
</http>
<beans:beans profile="PRO">
<beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg value="ldap://${ldap.host}:${ldap.port}"/>
<beans:property name="userDn" value="${ldap.userdn}"/>
<beans:property name="password" value="${ldap.passw}"/>
</beans:bean>
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="contextSource"/>
<beans:property name="userSearch">
<beans:bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg value="${ldap.basedn}"/>
<beans:constructor-arg value="(bsalias={0})"/>
<beans:constructor-arg ref="contextSource"/>
</beans:bean>
</beans:property>
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean class="es.isban.atlas.views.web.core.authorization.AtlasAuthoritiesPopulator" />
</beans:constructor-arg>
</beans:bean>
<authentication-manager erase-credentials="false">
<authentication-provider ref="ldapAuthProvider" />
</authentication-manager>
</beans:beans>
<beans:beans profile="DES">
<authentication-manager erase-credentials="false">
<authentication-provider>
<user-service>
<user name="user" password="atlas" authorities="ROLE_USER" />
<user name="admin" password="atlas" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Do you have any clue? How can I fix that?
Thanks in advance.
This is a bug in the Spring Security Java Configuration that impacts the global authentication option. See SEC-2533 for details. There is not a real easy work around for this issue, but the bug is already fixed and a release will be out within the next few days.

Spring security - different SALTs at user creation and login time

I am facing again the same problem with Spring Security: "password does not match stored value".
I import 4 accounts in my graph (I'm using SpringData/Neo4J) with my custom GraphPopulator class and try to log in with one ("fbiville"/"s3cret").
The authentication is configured as follows:
<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
<beans:constructor-arg value="******" />
</beans:bean>
<beans:bean id="userService" class="com.lateralthoughts.devinlove.service.LoginService" />
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
And the class in charge of persisting accounts is partially based on a custom SpringData repository implementation:
class PersonRepositoryImpl implements PersonRepositoryCustom {
private final PasswordEncoder passwordEncoder;
private final Neo4jOperations template;
#Autowired
public PersonRepositoryImpl(PasswordEncoder passwordEncoder,
Neo4jOperations template) {
this.passwordEncoder = passwordEncoder;
this.template = template;
}
#Override
#Transactional
public void persist(Person person) {
person.setPassword(passwordEncoder.encode(person.getPassword()));
template.save(person);
}
}
Finally, the login process is configured as follows:
<http auto-config='true' use-expressions='true' realm="devinlove: love is just another algorithm">
<form-login login-page="/login"
default-target-url="/"
authentication-failure-url="/login" />
<intercept-url pattern="/login" access="isAnonymous()" />
<intercept-url pattern="/**" access="hasRole('USER')" />
</http>
I debugged the StandardPasswordEncoder at account creation and user login attempt, and I noticed the salts don't match, which obviously leads to an authentication error.
You can clone the repository if you wanna reproduce the problem.
Thanks in advance !
Rolf
You need to use org.springframework.security.authentication.encoding.PasswordEncoder implementation, rather then org.springframework.security.crypto.password.PasswordEncoder.
So you can simply use as the follows:
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder hash="sha" base64="true">
<!--Single salt - the very same as you are using in `encoder` instance-->
<salt-source system-wide="********"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
Note, that this will work properly with #Autowired properties, though there shouldn't be #Qualifier and beans have to be represented only once.
It exposes implementation of such interfaces: org.springframework.security.authentication.encoding.PasswordEncoder and org.springframework.security.authentication.dao.SaltSource.
So in your particular case it would look like as follows:
class PersonRepositoryImpl implements PersonRepositoryCustom {
private final PasswordEncoder passwordEncoder;
private final Neo4jOperations template;
#Autowired
public PersonRepositoryImpl(PasswordEncoder passwordEncoder,
SaltSource saltSource
Neo4jOperations template) {
this.passwordEncoder = passwordEncoder;
this.saltSource = saltSource;
this.template = template;
}
#Override
#Transactional
public void persist(Person person) {
person.setPassword(passwordEncoder.encode(person.getPassword(), saltSource));
template.save(person);
}
}

UserDetailsService Not Getting Called

I have this Spring XML:
<!-- Configure the authentication -->
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/login"
authentication-failure-url="/login?error=true"
default-target-url="/index" />
<security:logout invalidate-session="true"
logout-success-url="/login"
logout-url="/logout" />
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="testUDS" />
</security:authentication-manager>
<bean id="testUDS" class="net.safecycle.services.security.TestUserDetailService" />
My UserDetailsService implementation looks like this:
public class TestUserDetailService implements UserDetailsService {
public UserDetails loadUserByUsername
(
String username
) throws UsernameNotFoundException {
System.out.println ("loadUserByUsername (" + username + ")");
Collection<GrantedAuthority> authorities;
authorities = new LinkedList<GrantedAuthority> ();
authorities.add (new GrantedAuthorityImpl ("Admin"));
UserDetails ud = new User (username,
"ca",
true,
true,
true,
true,
authorities);
return ud;
}
}
When I log in with any username and the password 'ca', I should see the print statement at the top of my loadUserByUsername, but I do not. What is most perplexing is that I have used this code in another project with no problem. Is there anything I am missing, a copy mistake I'm hoping?
Here is my code from my xml file. Only missing thing is the allias.. try to add alias="authenticationManager" maybe it will help.
<beans:bean id="CustomUserDetailsService"
class="com.dennis.ehospital.hibernate.security.CustomUserDetailsService" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="CustomUserDetailsService" />
</authentication-manager>
Try to specify which resources are protected
<security:intercept-url pattern="/**" access="isAuthenticated()"/>

Categories