I have:
@Service
public class MyAppUserDetailsService implements UserDetailsService {
@Autowired
private IUserInfoDAO userInfoDAO;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User activeUserInfo = userInfoDAO.getActiveUser(userName);
GrantedAuthority authority = new SimpleGrantedAuthority(activeUserInfo.getRole());
String userNameVal = activeUserInfo.getUserName();
String userSurnameVal = activeUserInfo.getPassword();
UserDetails userDetails = new org.springframework.security.core.userdetails.User(userNameVal, userSurnameVal, Arrays.asList(authority));
return userDetails;
}
}
and:
in security chain I configured:
.and().formLogin() //login configuration
.loginPage("/app/login")
.loginProcessingUrl("/app-login")
.usernameParameter("app_username")
.passwordParameter("app_password")
.defaultSuccessUrl("/app/secure/projects-details")
How user password fill in the form is compare to UserDetails set in loadUserByUsername method?
Once you tell the Spring Security Configuration that you will use a particular
UserDetailsService
or only one@Service
bean is an implementation of that interface, then Spring starts using it to fetch the user by username from your persistent storage. Let's simplify the flow:The user submits a form where fields with names
app_username
andapp_password
are present (as configured in Web Security Config) to theloginPage(String)
routeThe form submission is intercepted by the Spring Security's Filter Chain and Spring is aware that the username is in the field
app_username
and the password is in the fieldapp_password
The configured
UserDetailsService
bean is now activated, at itsloadUserByUsername(String)
method is invoked and the value ofapp_username
field is passed (e.g.john_smith
)As the
loadUserByUsername(String)
method is by contract designed to return an implementation ofUserDetails
it always returns an object which containsgetUsername()
andgetPassword()
methodsSpring then uses the
getPassword()
method from the contract and compares the password withapp_password
field (e.g.super_s3cr3t_password
)If
passwordEncoder()
is configured in the Spring Security Config or an implementation ofPasswordEncoder
interface is registered as bean, then spring uses theisPasswordValid(String, String, Object)
method to verify the contents ofapp_password
field and the result ofUserDetails.getPassword()
methodIf the
UserDetailsService
does not throwUsernameNotFoundException
and the fetchedUserDetails
'sgetPassword()
matches theapp_password
the filter chain continues executing the other filters, otherwise it prevents the user from logging into the applicationIf a code example simplifies it better, then imagine the following pseudo-java-code:
Keep in mind this is not the Spring Security Code behind the scenes, but just a simplified code illustration of the explanation.