* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/
public UserDetails loadUserByUsername(String name)
throws UsernameNotFoundException, DataAccessException {
Site site = securityService.getSite();
if (site == null) {
logger.error("Site context not available during user lookup");
throw new UsernameNotFoundException("No site context available");
}
User user = loadUser(name, site);
if (user == null) {
throw new UsernameNotFoundException(name);
} else {
// By default, add the anonymous role so the user is able to access
// publicly available resources
user.addPublicCredentials(SystemRole.GUEST);
// Collect the set of roles (granted authorities) for this users
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for (Object o : user.getPublicCredentials(Role.class)) {
Role masterRole = (Role) o;
for (Role r : masterRole.getClosure()) {
authorities.add(new SimpleGrantedAuthority(r.getContext() + ":" + r.getIdentifier()));
// Every role may or may not be a system role or - in case of non-
// system roles, may or may not be including one or more of those
// roles. Let's ask for a translation and then add those roles
// to the set of granted authorities
Role[] systemEquivalents = getSystemRoles(r);
for (Role systemRole : systemEquivalents) {
authorities.add(new SimpleGrantedAuthority(systemRole.getContext() + ":" + systemRole.getIdentifier()));
user.addPublicCredentials(systemRole);
}
}
}
// Make sure there is no ambiguous information with regards to passwords
Set<Object> passwords = user.getPrivateCredentials(Password.class);
if (passwords.size() > 1) {
logger.warn("User '{}@{}' has more than one password'", name, site.getIdentifier());
throw new DataRetrievalFailureException("User '" + user + "' has more than one password");
} else if (passwords.size() == 0) {
logger.warn("User '{}@{}' has no password", name, site.getIdentifier());
throw new DataRetrievalFailureException("User '" + user + "' has no password");
}
// Create the password according to the site's and Spring Security's
// digest policy
Password p = (Password) passwords.iterator().next();
String password = null;
switch (site.getDigestType()) {
case md5:
if (!DigestType.md5.equals(p.getDigestType())) {
logger.debug("Creating digest password for '{}@{}'", name, site.getIdentifier());
password = PasswordEncoder.encode(p.getPassword());
} else {
password = p.getPassword();
}
break;
case plain:
if (!DigestType.plain.equals(p.getDigestType())) {
logger.warn("User '{}@{}' does not have a plain text password'", name, site.getIdentifier());
return null;
}
password = p.getPassword();
break;
default:
throw new IllegalStateException("Unknown digest type '" + site.getDigestType() + "'");
}
// Notifiy login listeners of the initiated login attempt
for (LoginListener listener : loginListeners) {
try {