package org.synyx.urlaubsverwaltung.security;
import org.apache.log4j.Logger;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.synyx.urlaubsverwaltung.core.person.Person;
import org.synyx.urlaubsverwaltung.core.person.PersonService;
import org.synyx.urlaubsverwaltung.core.person.Role;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Provides authentication with password, which is saved in database.
*
* @author Daniel Hammann - <hammann@synyx.de>
*/
public class SimpleAuthenticationProvider implements AuthenticationProvider {
private static final Logger LOG = Logger.getLogger(SimpleAuthenticationProvider.class);
private final PersonService personService;
public SimpleAuthenticationProvider(PersonService personService) {
this.personService = personService;
}
@Override
public Authentication authenticate(Authentication authentication) {
StandardPasswordEncoder encoder = new StandardPasswordEncoder();
String username = authentication.getName();
String rawPassword = authentication.getCredentials().toString();
Optional<Person> userOptional = personService.getPersonByLogin(username);
if (!userOptional.isPresent()) {
LOG.info("No user found for username '" + username + "'");
throw new UsernameNotFoundException("No authentication possible for user = " + username);
}
Person person = userOptional.get();
if (person.hasRole(Role.INACTIVE)) {
LOG.info("User '" + username + "' has been deactivated and can not sign in therefore");
throw new DisabledException("User '" + username + "' has been deactivated");
}
Collection<Role> permissions = person.getPermissions();
Collection<GrantedAuthority> grantedAuthorities = permissions.stream().map((role) ->
new SimpleGrantedAuthority(role.name())).collect(Collectors.toList());
String userPassword = person.getPassword();
if (encoder.matches(rawPassword, userPassword)) {
LOG.info("User '" + username + "' has signed in with roles: " + grantedAuthorities);
return new UsernamePasswordAuthenticationToken(username, userPassword, grantedAuthorities);
} else {
LOG.info("User '" + username + "' has tried to sign in with a wrong password");
throw new BadCredentialsException("The provided password is wrong");
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}