package net.pechorina.kontempl.service; import net.pechorina.kontempl.utils.StringUtils; import org.apache.commons.codec.digest.DigestUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.MessageSource; import org.springframework.core.env.Environment; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import java.util.*; import java.util.stream.Collectors; @Service("localAuthProvider") public class LocalAuthProvider implements AuthenticationProvider { static final Logger logger = LoggerFactory.getLogger(LocalAuthProvider.class); protected boolean hideUserNotFoundExceptions = false; // protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor(); @Autowired private Environment env; @Autowired @Qualifier("customUserDetailsService") private UserDetailsService userDetailsService; @Autowired //@Qualifier("securityMessageSource") MessageSource messages; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, messages.getMessage("UsernamePasswordAuthenticationToken.onlySupports", null, "Only UsernamePasswordAuthenticationToken is supported", Locale.getDefault())); UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; String username = String.valueOf(auth.getPrincipal()); String password = String.valueOf(auth.getCredentials()); // clean username and password username = username.toLowerCase(); username = StringUtils.superTrim(username); password = StringUtils.superTrim(password); logger.debug("username: `" + username + "`"); logger.debug("password: `" + password + "`"); // 1. Use the username to load the data for the user, including // authorities and password. UserDetails ud; try { ud = userDetailsService.loadUserByUsername(username); } catch (UsernameNotFoundException notFound) { if (hideUserNotFoundExceptions) { logger.warn("username not found: " + username); throw new BadCredentialsException(messages.getMessage( "LocalAuthProvider.badCredentials", null, "Bad credentials", Locale.getDefault())); } else { throw notFound; } } // 2. Check the passwords match. if (!ud.getPassword().equals(DigestUtils.sha1Hex(password))) { throw new BadCredentialsException(messages.getMessage( "LocalAuthProvider.incorrectPassword", null, "Bad password", Locale.getDefault())); } // 3. Return an authenticated token, containing user data and // authorities return new UsernamePasswordAuthenticationToken(ud, null, ud.getAuthorities()); } public Collection<? extends GrantedAuthority> getAuthorities(List<String> aasRoles) { List<GrantedAuthority> temp = aasRoles.stream().map(roleName -> new SimpleGrantedAuthority("ROLE_" + roleName.toUpperCase())).collect(Collectors.toList()); return Collections.unmodifiableList(temp); } @Override public boolean supports(Class<?> authentication) { return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); } }