while experimenting around with spring boot, security, and data.
i just came across this scenario:
i use H2 in memory DB and poblate it with one user with liquibase on startup with username and password.
now i want spring security to authenticate against H2. for that purpose i have this code:
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceImp);
}
and im implementing the userDetails as follows:
@Override
public UserDetails loadUserByUsername(String username) {
//this works, the user with pass is pulled
com.fix.demo.logic.user.User byUsername =
userRepository.findByUsername(username);
if (byUsername == null) {
System.out.println("No user found with username: ");
return null; //trow ex here
}
User user = new User(byUsername.getUsername(),
byUsername.getPassword(), true, true,
true, true, getAuthorities(Collections.singletonList("user")));
//System.out.println(user.toString());
//System.out.println(byUsername.toString()+ " "+byUsername.getPassword());
return user;
}
but my tests keep failing with
Authentication should not be null
and trying to log in will give me
bad credentials
what is necessary for my custom implementation of UserDetailsService to work?
this is the failing test:
@Test
public void loginWithValidUserThenAuthenticated() throws Exception {
FormLoginRequestBuilder login = formLogin()
.user("admin")
.password("root");
mockMvc.perform(login)
.andExpect(authenticated().withUsername("admin"));
}
One of the reasons is, the password might my encoded and you need to tell spring security to use an encoder. Add the following line to the configure override.
auth.setPasswordEncoder(passwordEncoder());
define the passwordEncoder bean.
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}