springcloud_k8s_panzhihuazhihuishequ/auth/src/main/java/com/panzhihua/auth/config/MyAESUtil.java
New file @@ -0,0 +1,52 @@ package com.panzhihua.auth.config; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class MyAESUtil { // 加密 public static String Encrypt(String sSrc, String sKey) throws Exception { if (sKey == null) { System.out.print("Key为空null"); return null; } // 判断Key是否为16位 if (sKey.length() != 16) { System.out.print("Key长度不是16位"); return null; } byte[] raw = sKey.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式" cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8")); return new BASE64Encoder().encode(encrypted);//此处使用BASE64做转码功能,同时能起到2次加密的作用。 } // 解密 public static String Decrypt(String sSrc, String sKey) throws Exception { try { byte[] raw = sKey.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//先用base64解密 try { byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original,"utf-8"); return originalString; } catch (Exception e) { System.out.println(e.toString()); return null; } } catch (Exception ex) { System.out.println(ex.toString()); return null; } } } springcloud_k8s_panzhihuazhihuishequ/auth/src/main/java/com/panzhihua/auth/handel/UserAuthenticationProvider.java
@@ -1,11 +1,22 @@ 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.model.helper.AESUtil; 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; @@ -33,17 +44,34 @@ public class UserAuthenticationProvider implements AuthenticationProvider { @Resource private UserService userService; @Resource private RedisTemplate redisTemplate; 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(); String password =(String)authentication.getCredentials(); 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, Duration.ofMinutes(5)); throw new LockedException("登录错误超过限制,请五分钟后重试"); } } // 查询用户是否存在 R<LoginUserInfoVO> r = userService.getUserInfo(userName); if (r.getCode() != 200) { throw new UsernameNotFoundException("该账号不存在"); lockLogin(flag,userName); throw new UsernameNotFoundException("账号或密码错误"); } LoginUserInfoVO loginUserInfoVO = r.getData(); List<GrantedAuthority> grantedAuthorityList = new ArrayList<>(); @@ -53,11 +81,13 @@ grantedAuthorityList.add(new SimpleGrantedAuthority(s)); }); } if (ObjectUtils.isEmpty(loginUserInfoVO.getAccount())) { throw new UsernameNotFoundException("该账号不存在"); 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("密码不正确"); } // 还可以加一些其他信息的判断,比如用户账号已停用等判断 @@ -73,4 +103,14 @@ 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)); } } } springcloud_k8s_panzhihuazhihuishequ/auth/src/main/resources/bootstrap.yml
@@ -29,4 +29,10 @@ metrics: tags: application: auth application: auth #实体加密、解密、字段脱敏拦截设置 domain: decrypt: true encrypt: true aesKey: Ryo7M3n8loC5 sensitive: true springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java
@@ -2191,7 +2191,7 @@ SysUserDO sysUserDO = userDao .selectOne(new QueryWrapper<SysUserDO>().lambda().eq(SysUserDO::getPhone, phone).eq(SysUserDO::getType, 1)); if (ObjectUtils.isEmpty(sysUserDO)) { return R.fail("用户不存在"); return R.fail("账号或密码错误"); } SysUserVO sysUserVO = new SysUserVO(); BeanUtils.copyProperties(sysUserDO, sysUserVO); @@ -2226,7 +2226,7 @@ query.eq(SysUserDO::getType, type); SysUserDO sysUserDO = userDao.selectOne(query); if (ObjectUtils.isEmpty(sysUserDO)) { return R.fail("用户不存在"); return R.fail("账号或密码错误"); } SysUserVO sysUserVO = new SysUserVO(); BeanUtils.copyProperties(sysUserDO, sysUserVO); @@ -2991,7 +2991,7 @@ public R getUserInfoByUnionId(String unionId) { SysUserDO sysUserDO = userDao.selectOne(new QueryWrapper<SysUserDO>().lambda().eq(SysUserDO::getUnionid, unionId)); if (isNull(sysUserDO)) { return R.fail("用户不存在"); return R.fail("账号或密码错误"); } LoginUserInfoVO loginUserInfoVO = new LoginUserInfoVO(); BeanUtils.copyProperties(sysUserDO, loginUserInfoVO);