【用户信息】增加返回字段,加密接口
This commit is contained in:
@@ -721,4 +721,9 @@ public interface CommonConstant {
|
|||||||
* 多选
|
* 多选
|
||||||
*/
|
*/
|
||||||
String PD = "PD";
|
String PD = "PD";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* url加解密密钥(AES)
|
||||||
|
*/
|
||||||
|
String URL_SECRET_KEY = "a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package org.jeecg.util;
|
||||||
|
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES/CBC/PKCS5Padding 对称加密工具类
|
||||||
|
* 加密结果经 Base64 URL Safe(无填充)编码,可安全用于 URL 传参
|
||||||
|
*/
|
||||||
|
public class AesEncryptUtils {
|
||||||
|
|
||||||
|
private static final String ALGORITHM = "AES";
|
||||||
|
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
||||||
|
/**
|
||||||
|
* CBC 模式 IV 固定 16 字节
|
||||||
|
*/
|
||||||
|
private static final int IV_LENGTH = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
* 随机生成 IV,将 [IV(16字节) + 密文] 拼接后进行 Base64 URL Safe(无填充)编码
|
||||||
|
*
|
||||||
|
* @param plainText 明文字符串
|
||||||
|
* @param secretKey 密钥(任意长度字符串,内部经 SHA-256 截取为 128 位)
|
||||||
|
* @return URL 安全的密文字符串,不含 +、/、= 等特殊字符
|
||||||
|
* @throws Exception 加密异常
|
||||||
|
*/
|
||||||
|
public static String encrypt(String plainText, String secretKey) throws Exception {
|
||||||
|
byte[] keyBytes = deriveKey(secretKey);
|
||||||
|
byte[] ivBytes = generateIv();
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE,
|
||||||
|
new SecretKeySpec(keyBytes, ALGORITHM),
|
||||||
|
new IvParameterSpec(ivBytes));
|
||||||
|
byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
|
||||||
|
// 将 IV 前缀拼接到密文,解密时从头部分离
|
||||||
|
byte[] combined = new byte[IV_LENGTH + encrypted.length];
|
||||||
|
System.arraycopy(ivBytes, 0, combined, 0, IV_LENGTH);
|
||||||
|
System.arraycopy(encrypted, 0, combined, IV_LENGTH, encrypted.length);
|
||||||
|
return Base64.getUrlEncoder().withoutPadding().encodeToString(combined);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密
|
||||||
|
* 从密文头部分离 IV,再执行 AES/CBC 解密
|
||||||
|
*
|
||||||
|
* @param cipherText URL 安全的密文字符串(由 encrypt 方法生成)
|
||||||
|
* @param secretKey 密钥(须与加密时保持一致)
|
||||||
|
* @return 解密后的明文字符串
|
||||||
|
* @throws Exception 解密异常(密钥错误或数据被篡改时抛出)
|
||||||
|
*/
|
||||||
|
public static String decrypt(String cipherText, String secretKey) throws Exception {
|
||||||
|
byte[] combined = Base64.getUrlDecoder().decode(cipherText);
|
||||||
|
byte[] ivBytes = Arrays.copyOfRange(combined, 0, IV_LENGTH);
|
||||||
|
byte[] encrypted = Arrays.copyOfRange(combined, IV_LENGTH, combined.length);
|
||||||
|
byte[] keyBytes = deriveKey(secretKey);
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE,
|
||||||
|
new SecretKeySpec(keyBytes, ALGORITHM),
|
||||||
|
new IvParameterSpec(ivBytes));
|
||||||
|
return new String(cipher.doFinal(encrypted), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 SHA-256 对密钥字符串进行哈希,取前 16 字节作为 AES 128 位密钥
|
||||||
|
* 支持任意长度的密钥输入,避免 AES 对密钥长度的严格限制
|
||||||
|
*
|
||||||
|
* @param secretKey 原始密钥字符串
|
||||||
|
* @return 16 字节的 AES 密钥
|
||||||
|
*/
|
||||||
|
private static byte[] deriveKey(String secretKey) throws Exception {
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
byte[] hash = digest.digest(secretKey.getBytes(StandardCharsets.UTF_8));
|
||||||
|
// 取前 16 字节 = 128 位 AES 密钥
|
||||||
|
return Arrays.copyOf(hash, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 SecureRandom 随机生成 16 字节 IV
|
||||||
|
* 每次加密使用不同 IV,防止相同明文产生相同密文
|
||||||
|
*
|
||||||
|
* @return 16 字节随机 IV
|
||||||
|
*/
|
||||||
|
private static byte[] generateIv() {
|
||||||
|
byte[] iv = new byte[IV_LENGTH];
|
||||||
|
new SecureRandom().nextBytes(iv);
|
||||||
|
return iv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
String plainText = "https://hello world";
|
||||||
|
String secretKey = CommonConstant.URL_SECRET_KEY;
|
||||||
|
// String cipherText = AesEncryptUtils.encrypt(plainText, secretKey);
|
||||||
|
// System.out.println(cipherText);
|
||||||
|
String decryptedText = AesEncryptUtils.decrypt("6oFxHVMYNHXpz8VtsREcNlokVqOdvaZNSGBJ5U3_7mY", secretKey);
|
||||||
|
System.out.println(decryptedText);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -82,18 +82,36 @@ public class BaseEmployeeInfo {
|
|||||||
@Schema(title = "二级部门Code(单位)")
|
@Schema(title = "二级部门Code(单位)")
|
||||||
private String secondDeptCode;
|
private String secondDeptCode;
|
||||||
|
|
||||||
|
@Schema(title = "二级部门id(单位)")
|
||||||
|
private String secondDeptId;
|
||||||
|
|
||||||
@Schema(title = "二级部门名称(单位)")
|
@Schema(title = "二级部门名称(单位)")
|
||||||
private String secondDeptName;
|
private String secondDeptName;
|
||||||
|
|
||||||
@Schema(title = "三级部门Code(部门)")
|
@Schema(title = "三级部门Code(部门)")
|
||||||
private String thirdDeptCode;
|
private String thirdDeptCode;
|
||||||
|
|
||||||
|
@Schema(title = "三级部门id(部门)")
|
||||||
|
private String thirdDeptId;
|
||||||
|
|
||||||
@Schema(title = "三级部门名称(部门)")
|
@Schema(title = "三级部门名称(部门)")
|
||||||
private String thirdDeptName;
|
private String thirdDeptName;
|
||||||
|
|
||||||
@Schema(title = "当前部门Code(用户所属部门)")
|
@Schema(title = "当前部门Code(用户所属部门)")
|
||||||
private String thisDeptCode;
|
private String thisDeptCode;
|
||||||
|
|
||||||
|
@Schema(title = "当前部门id(用户所属部门)")
|
||||||
|
private String thisDeptId;
|
||||||
|
|
||||||
@Schema(title = "当前部门名称(用户所属部门)")
|
@Schema(title = "当前部门名称(用户所属部门)")
|
||||||
private String thisDeptName;
|
private String thisDeptName;
|
||||||
|
|
||||||
|
@Schema(title = "角色编码")
|
||||||
|
private String roleCodes;
|
||||||
|
|
||||||
|
@Schema(title = "管理部门(code)")
|
||||||
|
private String departCodes;
|
||||||
|
|
||||||
|
@Schema(title = "管理部门(id)")
|
||||||
|
private String departIds;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -3,16 +3,20 @@ package org.jeecg.modules.api.controller;
|
|||||||
import org.jeecg.base.UserBase;
|
import org.jeecg.base.UserBase;
|
||||||
import org.jeecg.bean.response.BaseEmployeeInfo;
|
import org.jeecg.bean.response.BaseEmployeeInfo;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.modules.system.bean.response.ScalePersonalUserInfo;
|
import org.jeecg.modules.system.bean.response.ScalePersonalUserInfo;
|
||||||
import org.jeecg.modules.system.service.ISysUserService;
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
import org.jeecg.modules.system.service.ScalePersonalService;
|
import org.jeecg.modules.system.service.ScalePersonalService;
|
||||||
|
import org.jeecg.util.AesEncryptUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author stan
|
* @author stan
|
||||||
@@ -67,5 +71,14 @@ public class SysApiController {
|
|||||||
return Result.ok(sysUserService.getUserInfo());
|
return Result.ok(sysUserService.getUserInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串加密
|
||||||
|
*/
|
||||||
|
@GetMapping("encryptInfo")
|
||||||
|
public Result<Map<String, String>> encryptInfo(@RequestParam String str) throws Exception {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map.put("encryptData", AesEncryptUtils.encrypt(str, CommonConstant.URL_SECRET_KEY));
|
||||||
|
return Result.ok(map);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+16
@@ -3906,6 +3906,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||||||
if (null == loginUser) {
|
if (null == loginUser) {
|
||||||
ExceptionAssertsUtil.fail("用户不存在!");
|
ExceptionAssertsUtil.fail("用户不存在!");
|
||||||
}
|
}
|
||||||
|
List<String> managedCodes = GlobalUtils.getManagedCodes(null);
|
||||||
|
Set<String> departIds = new HashSet<>();
|
||||||
|
if (CollUtil.isNotEmpty(managedCodes)) {
|
||||||
|
managedCodes.forEach(s -> {
|
||||||
|
String departIdByOrgCode = sysCache.getDepartIdByOrgCode(s);
|
||||||
|
if (StringUtils.isNotBlank(departIdByOrgCode) && !"null".equals(departIdByOrgCode)) {
|
||||||
|
departIds.add(departIdByOrgCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
MPJLambdaWrapper<SysUser> queryWrapper = new MPJLambdaWrapper<SysUser>()
|
MPJLambdaWrapper<SysUser> queryWrapper = new MPJLambdaWrapper<SysUser>()
|
||||||
.selectAs(SysUser::getId, BaseEmployeeInfo::getUserId)
|
.selectAs(SysUser::getId, BaseEmployeeInfo::getUserId)
|
||||||
.selectAs(SysUser::getUsername, BaseEmployeeInfo::getUserName)
|
.selectAs(SysUser::getUsername, BaseEmployeeInfo::getUserName)
|
||||||
@@ -3931,13 +3941,19 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||||||
baseEmployeeInfo.setAge(ObjectUtils.isNotEmpty(loginUser.getAge()) && loginUser.getAge() > 0 ? loginUser.getAge() : null);
|
baseEmployeeInfo.setAge(ObjectUtils.isNotEmpty(loginUser.getAge()) && loginUser.getAge() > 0 ? loginUser.getAge() : null);
|
||||||
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(loginUser.getOrgCode()));
|
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(loginUser.getOrgCode()));
|
||||||
baseEmployeeInfo.setSecondDeptCode(secondDepart.getOrgCode());
|
baseEmployeeInfo.setSecondDeptCode(secondDepart.getOrgCode());
|
||||||
|
baseEmployeeInfo.setSecondDeptId(secondDepart.getId());
|
||||||
baseEmployeeInfo.setSecondDeptName(secondDepart.getDepartName());
|
baseEmployeeInfo.setSecondDeptName(secondDepart.getDepartName());
|
||||||
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(loginUser.getOrgCode()));
|
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(loginUser.getOrgCode()));
|
||||||
baseEmployeeInfo.setThirdDeptCode(thirdDepart.getOrgCode());
|
baseEmployeeInfo.setThirdDeptCode(thirdDepart.getOrgCode());
|
||||||
|
baseEmployeeInfo.setThirdDeptId(thirdDepart.getId());
|
||||||
baseEmployeeInfo.setThirdDeptName(thirdDepart.getDepartName());
|
baseEmployeeInfo.setThirdDeptName(thirdDepart.getDepartName());
|
||||||
baseEmployeeInfo.setThisDeptCode(loginUser.getOrgCode());
|
baseEmployeeInfo.setThisDeptCode(loginUser.getOrgCode());
|
||||||
SysDepart departByOrgCode = sysCache.getDepartByOrgCode(loginUser.getOrgCode());
|
SysDepart departByOrgCode = sysCache.getDepartByOrgCode(loginUser.getOrgCode());
|
||||||
baseEmployeeInfo.setThisDeptName(departByOrgCode.getDepartName());
|
baseEmployeeInfo.setThisDeptName(departByOrgCode.getDepartName());
|
||||||
|
baseEmployeeInfo.setThisDeptId(departByOrgCode.getId());
|
||||||
|
baseEmployeeInfo.setRoleCodes(loginUser.getRoleCodes());
|
||||||
|
baseEmployeeInfo.setDepartCodes(String.join(",", managedCodes));
|
||||||
|
baseEmployeeInfo.setDepartIds(String.join(",", departIds));
|
||||||
return baseEmployeeInfo;
|
return baseEmployeeInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user