We will implement UserDetailsService inside the existing UserApplicationServiceImpl and let's change the UserApplicationService interface to extend UserDetailsService, as shown here:
public interface UserApplicationService extends UserDetailsService {
...
}
Here is the change to UserApplicationServiceImpl:
...
public class UserApplicationServiceImpl implements UserApplicationService {
...
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (StringUtils.isEmpty(username)) {
throw new UsernameNotFoundException("No user found");
}
User user;
if (username.contains("@")) {
user = userRepository.findByEmailAddress(username);
} else {
user = userRepository.findByUsername(username);
}
if (user == null) {
throw new UsernameNotFoundException("No user found by `" +
username + "`");
}
return new SimpleUser(user);
}
...
}
As you can see, we add a reference to UserRepository here. Inside the loadUserByUsername() method, we make sure username is not empty; otherwise, we simply throw the exception with no need to go further. The way of finding the user depends on whether the username property contains an @ or not. When no user is found, we throw an exception. Otherwise, we return an instance of SimpleUser, which implements the UserDetails interface.