Dovrebbe essere in un livello di servizio.
public interface UserService {
public void findByLogin(final String userName);
}
E in un'implementazione del servizio:
public class UserServiceImpl implements UserService {
@Inject
private UserRepository userRepository;
public User findByLogin(final String userName, final String password) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(userName), "Username is mandatory !");
return Preconditions.checkNotNull(userRepository.findByLogin(userName), "User not found !");
}
}
E un servizio di provider di identità:
public class InternalIdentityProviderImpl implements ... {
@Inject
private UserService userService;
public void authenticate(final String login, final String password) throws BadCredentialsException, IdentityNotFoundException {
try {
Preconditions.checkArgument(!Strings.isNullOrEmpty(login), "Username is mandatory !");
Preconditions.checkArgument(!Strings.isNullOrEmpty(password), "Username is mandatory !");
catch(Exception e) {
throw new BadCredentialsException(e);
}
// Check user
try {
User internal = Preconditions.checkNotNull(userService.findByLogin(username));
} catch(Exception e) {
// logs
throw new IdentityNotFoundException(e);
}
// Shiro authentication
Subject user = SecurityUtils.getSubject();
user.login(new UsernamePasswordToken(username, password));
}
}
Dovresti personalizzare il modo in cui l'utente viene richiamato dal provider di identità e come viene convalidato dal tuo sistema di identificazione.
Attualmente ho usato RuntimeException lanciata da Guava Preconditions, ma puoi usare una specifica eccezione Handcrafted.
vale a dire:
- IdentityNotFoundException: dal tuo provider di identità.
- BadCredentialsException: dal tuo sistema di identificazione.
Questo servizio potrebbe essere chiamato dal controller e gestire l'eccezione per visualizzare il messaggio corretto.