package com.panzhihua.auth.handel; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.annotation.Resource; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import com.panzhihua.auth.config.MyAESUtil; import com.panzhihua.common.constants.Constants; import com.panzhihua.common.model.helper.AESUtil; import com.panzhihua.common.service.community.CommunityService; import com.panzhihua.common.utlis.AES; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.LockedException; 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.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import com.panzhihua.common.model.vos.LoginUserInfoVO; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.service.user.UserService; import static java.util.Objects.nonNull; /** * @program: springcloud_k8s_panzhihuazhihuishequ * @description: 登录认证 * @author: huang.hongfa weixin hhf9596 qq 959656820 * @create: 2020-11-24 16:14 **/ @Component public class UserAuthenticationProvider implements AuthenticationProvider { @Resource private UserService userService; @Resource private RedisTemplate redisTemplate; @Resource private CommunityService communityService; private static String LOGIN_FAIL="LOGIN_FAIL_"; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 获取表单输入中返回的用户名 String userName = (String)authentication.getPrincipal(); String password =(String)authentication.getCredentials(); if(!userName.contains("_1")&&!userName.contains("_6")){ try { password = MyAESUtil.Decrypt((String)authentication.getCredentials(),"Ryo7M3n8loC5Abcd"); } catch (Exception e) { e.printStackTrace(); } boolean flag= redisTemplate.hasKey(LOGIN_FAIL+userName); if(flag){ Integer time= (Integer) redisTemplate.opsForValue().get(LOGIN_FAIL+userName); if(time>=5){ redisTemplate.opsForValue().set(LOGIN_FAIL+userName,5); throw new LockedException("账号或密码错误,登录错误超过限制"); } } // 查询用户是否存在 R r = userService.getUserInfo(userName); if (r.getCode() != 200) { lockLogin(flag,userName); throw new UsernameNotFoundException("账号或密码错误"); } LoginUserInfoVO loginUserInfoVO = r.getData(); List grantedAuthorityList = new ArrayList<>(); Set roles = loginUserInfoVO.getRoles(); if (!ObjectUtils.isEmpty(roles)) { roles.forEach(s -> { grantedAuthorityList.add(new SimpleGrantedAuthority(s)); }); } if (ObjectUtils.isEmpty(loginUserInfoVO.getAccount())||ObjectUtils.isEmpty(password)) { lockLogin(flag,userName); throw new UsernameNotFoundException("账号或密码错误"); } // 我们还要判断密码是否正确,这里我们的密码使用BCryptPasswordEncoder进行加密的 if (!new BCryptPasswordEncoder().matches(password, loginUserInfoVO.getPassword())) { lockLogin(flag,userName); throw new BadCredentialsException("账号或密码错误"); } // 还可以加一些其他信息的判断,比如用户账号已停用等判断 if (loginUserInfoVO.getStatus().intValue() == 2) { throw new LockedException("该用户已被禁用"); } // 维护最后登录时间 userService.putUserLastLoginTime(loginUserInfoVO.getUserId()); //是否为专家登陆 if (nonNull(loginUserInfoVO.getPhone())){ R r1 = communityService.isExpert(loginUserInfoVO.getPhone()); if (r1.getCode()== Constants.SUCCESS){ loginUserInfoVO.setType(13); } } return new UsernamePasswordAuthenticationToken(loginUserInfoVO, password, grantedAuthorityList); } else { // 查询用户是否存在 R r = userService.getUserInfo(userName); if (r.getCode() != 200) { throw new UsernameNotFoundException("账号或密码错误"); } LoginUserInfoVO loginUserInfoVO = r.getData(); List grantedAuthorityList = new ArrayList<>(); Set roles = loginUserInfoVO.getRoles(); if (!ObjectUtils.isEmpty(roles)) { roles.forEach(s -> { grantedAuthorityList.add(new SimpleGrantedAuthority(s)); }); } if (ObjectUtils.isEmpty(loginUserInfoVO.getAccount())) { throw new UsernameNotFoundException("账号或密码错误"); } // 我们还要判断密码是否正确,这里我们的密码使用BCryptPasswordEncoder进行加密的 if (!new BCryptPasswordEncoder().matches(password, loginUserInfoVO.getPassword())) { throw new BadCredentialsException("账号或密码错误"); } // 还可以加一些其他信息的判断,比如用户账号已停用等判断 if (loginUserInfoVO.getStatus().intValue() == 2) { throw new LockedException("该用户已被禁用"); } // 维护最后登录时间 userService.putUserLastLoginTime(loginUserInfoVO.getUserId()); //是否为专家登陆 if (nonNull(loginUserInfoVO.getPhone())){ R r1 = communityService.isExpert(loginUserInfoVO.getPhone()); if (r1.getCode() == Constants.SUCCESS){ loginUserInfoVO.setType(13); } } return new UsernamePasswordAuthenticationToken(loginUserInfoVO, password, grantedAuthorityList); } } @Override public boolean supports(Class aClass) { return true; } private void lockLogin(Boolean flag,String userName){ if(flag){ Integer time= (Integer) redisTemplate.opsForValue().get(LOGIN_FAIL+userName); redisTemplate.opsForValue().set(LOGIN_FAIL+userName,time+1, Duration.ofMinutes(5)); } else { redisTemplate.opsForValue().set(LOGIN_FAIL+userName,1, Duration.ofMinutes(5)); } } }