I have a login page where the user need put the below information VIN number,email, zip code and accessCode which they will get from different application.
So to val
It is not the responisibility of UserDetailsService to validate the Authentication token. This is what an AuthenticationProvider does.
So first leave your implementation of UserDetailsService the single responsibility of loading all the data of the user from the database by login:
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepository userRepository;
@Autowired
public UserDetailsServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = null;
try {
user = userRepository.findByUsername(username);
} catch (NotFoundException e) {
throw new UsernameNotFoundException(String.format("No user found for username %s!", username);
}
retrun new UserDetailsImpl(user);
}
}
Than to intercept additional parameters from a login form you need to implement AuthenticationDetailsSource. It may be a good idea to extend WebAuthenticationDetails, but you can have just any object returned by AuthenticationDetailsSource.
@Component
public class WebAuthenticationDetailsSourceImpl implements AuthenticationDetailsSource {
@Override
public MyWebAuthenticationDetails buildDetails(HttpServletRequest context) {
// the constructor of MyWebAuthenticationDetails can retrieve
// all extra parameters given on a login form from the request
// MyWebAuthenticationDetails is your LoginDetails class
return new MyWebAuthenticationDetails(context);
}
}
And to do the validation implement your own AuthenticationProvider by either implementing the interface itself or extending AbstractUserDetailsAuthenticationProvider or DaoAuthenticationProvider:
@Component
public class UserDetailsAuthenticationProviderImpl extends AbstractUserDetailsAuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
MyWebAuthenticationDetails detais = (MyWebAuthenticationDetails) authentication.getDetails();
// verify the authentication details here !!!
// and return proper authentication token (see DaoAuthenticationProvider for example)
}
}
Than you just need to pass your implementations to AuthenticationManager and UsernamePasswordAuthenticationFilter.
Hope this helps!
P.S. Consider constructor injection over field injection! It's more testable and states the contract of the class better. See this discussion.