Browse Source

api接口加密

master
zhouyl 1 year ago
parent
commit
eda83b16c7
  1. 13
      tp-admin/src/main/java/com/inscloudtech/web/controller/system/SysProfileController.java
  2. 2
      tp-admin/src/main/resources/application.yml
  3. 29
      tp-common/src/main/java/com/inscloudtech/common/core/domain/dto/SysUserPasswordBo.java
  4. 2
      tp-common/src/main/java/com/inscloudtech/common/encrypt/annotation/ApiEncrypt.java
  5. 7
      tp-common/src/main/java/com/inscloudtech/common/encrypt/annotation/EncryptField.java
  6. 8
      tp-common/src/main/java/com/inscloudtech/common/encrypt/config/ApiDecryptAutoConfiguration.java
  7. 49
      tp-common/src/main/java/com/inscloudtech/common/encrypt/config/EncryptorAutoConfiguration.java
  8. 6
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/EncryptContext.java
  9. 158
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/EncryptorManager.java
  10. 6
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/IEncryptor.java
  11. 6
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/AbstractEncryptor.java
  12. 10
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/AesEncryptor.java
  13. 11
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/Base64Encryptor.java
  14. 10
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/RsaEncryptor.java
  15. 11
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/Sm2Encryptor.java
  16. 10
      tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/Sm4Encryptor.java
  17. 7
      tp-common/src/main/java/com/inscloudtech/common/encrypt/enumd/AlgorithmType.java
  18. 2
      tp-common/src/main/java/com/inscloudtech/common/encrypt/enumd/EncodeType.java
  19. 16
      tp-common/src/main/java/com/inscloudtech/common/encrypt/filter/CryptoFilter.java
  20. 4
      tp-common/src/main/java/com/inscloudtech/common/encrypt/filter/DecryptRequestBodyWrapper.java
  21. 9
      tp-common/src/main/java/com/inscloudtech/common/encrypt/filter/EncryptResponseBodyWrapper.java
  22. 30
      tp-common/src/main/java/com/inscloudtech/common/encrypt/interceptor/MybatisDecryptInterceptor.java
  23. 32
      tp-common/src/main/java/com/inscloudtech/common/encrypt/interceptor/MybatisEncryptInterceptor.java
  24. 4
      tp-common/src/main/java/com/inscloudtech/common/encrypt/properties/ApiDecryptProperties.java
  25. 8
      tp-common/src/main/java/com/inscloudtech/common/encrypt/properties/EncryptorProperties.java
  26. 2
      tp-common/src/main/java/com/inscloudtech/common/encrypt/utils/EncryptUtils.java
  27. 1
      tp-common/src/main/java/com/inscloudtech/common/filter/RepeatedlyRequestWrapper.java
  28. 3
      tp-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  29. 39
      tp-framework/src/main/java/com/inscloudtech/framework/config/EncryptorConfig.java
  30. 18
      tp-framework/src/main/java/com/inscloudtech/framework/handler/AllUrlHandler.java
  31. 96
      tp-framework/src/main/java/com/inscloudtech/framework/manager/EncryptorManager.java
  32. 72
      tp-functional/src/test/java/JvmMemoryTest.java

13
tp-admin/src/main/java/com/inscloudtech/web/controller/system/SysProfileController.java

@ -5,7 +5,9 @@ import cn.hutool.core.io.FileUtil;
import com.inscloudtech.common.annotation.Log;
import com.inscloudtech.common.core.controller.BaseController;
import com.inscloudtech.common.core.domain.R;
import com.inscloudtech.common.core.domain.dto.SysUserPasswordBo;
import com.inscloudtech.common.core.domain.entity.SysUser;
import com.inscloudtech.common.encrypt.annotation.ApiEncrypt;
import com.inscloudtech.common.enums.BusinessType;
import com.inscloudtech.common.helper.LoginHelper;
import com.inscloudtech.common.utils.StringUtils;
@ -76,23 +78,22 @@ public class SysProfileController extends BaseController {
/**
* 重置密码
*
* @param newPassword 新密码
* @param oldPassword 旧密码
*/
@ApiEncrypt
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public R<Void> updatePwd(String oldPassword, String newPassword) {
public R<Void> updatePwd(@RequestBody SysUserPasswordBo bo) {
SysUser user = userService.selectUserById(LoginHelper.getUserId());
String userName = user.getUserName();
String password = user.getPassword();
if (!BCrypt.checkpw(oldPassword, password)) {
if (!BCrypt.checkpw(bo.getOldPassword(), password)) {
return R.fail("修改密码失败,旧密码错误");
}
if (BCrypt.checkpw(newPassword, password)) {
if (BCrypt.checkpw(bo.getNewPassword(), password)) {
return R.fail("新密码不能与旧密码相同");
}
if (userService.resetUserPwd(userName, BCrypt.hashpw(newPassword)) > 0) {
if (userService.resetUserPwd(userName, BCrypt.hashpw(bo.getNewPassword())) > 0) {
return R.ok();
}
return R.fail("修改密码异常,请联系管理员");

2
tp-admin/src/main/resources/application.yml

@ -82,6 +82,8 @@ spring:
# 热部署开关
enabled: true
mvc:
pathmatch:
matching-strategy: ant_path_matcher
format:
date-time: yyyy-MM-dd HH:mm:ss
jackson:

29
tp-common/src/main/java/com/inscloudtech/common/core/domain/dto/SysUserPasswordBo.java

@ -0,0 +1,29 @@
package com.inscloudtech.common.core.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* 用户密码修改bo
*/
@Data
public class SysUserPasswordBo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 旧密码
*/
@NotBlank(message = "旧密码不能为空")
private String oldPassword;
/**
* 新密码
*/
@NotBlank(message = "新密码不能为空")
private String newPassword;
}

2
tp-framework/src/main/java/com/inscloudtech/framework/encrypt/ApiEncrypt.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/annotation/ApiEncrypt.java

@ -1,4 +1,4 @@
package com.inscloudtech.framework.encrypt;
package com.inscloudtech.common.encrypt.annotation;
import java.lang.annotation.*;

7
tp-common/src/main/java/com/inscloudtech/common/annotation/EncryptField.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/annotation/EncryptField.java

@ -1,7 +1,8 @@
package com.inscloudtech.common.annotation;
package com.inscloudtech.common.encrypt.annotation;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import java.lang.annotation.*;

8
tp-framework/src/main/java/com/inscloudtech/framework/config/ApiDecryptAutoConfiguration.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/config/ApiDecryptAutoConfiguration.java

@ -1,7 +1,8 @@
package com.inscloudtech.framework.config;
package com.inscloudtech.common.encrypt.config;
import com.inscloudtech.framework.config.properties.ApiDecryptProperties;
import com.inscloudtech.framework.filter.CryptoFilter;
import com.inscloudtech.common.encrypt.filter.CryptoFilter;
import com.inscloudtech.common.encrypt.properties.ApiDecryptProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -10,7 +11,6 @@ import org.springframework.context.annotation.Bean;
import javax.servlet.DispatcherType;
/**
* api 解密自动配置
*

49
tp-common/src/main/java/com/inscloudtech/common/encrypt/config/EncryptorAutoConfiguration.java

@ -0,0 +1,49 @@
package com.inscloudtech.common.encrypt.config;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.inscloudtech.common.encrypt.core.EncryptorManager;
import com.inscloudtech.common.encrypt.interceptor.MybatisDecryptInterceptor;
import com.inscloudtech.common.encrypt.interceptor.MybatisEncryptInterceptor;
import com.inscloudtech.common.encrypt.properties.EncryptorProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* 加解密配置
*
* @author 老马
* @version 4.6.0
*/
@AutoConfiguration(after = MybatisPlusAutoConfiguration.class)
@EnableConfigurationProperties(EncryptorProperties.class)
@ConditionalOnProperty(value = "mybatis-encryptor.enable", havingValue = "true")
@Slf4j
public class EncryptorAutoConfiguration {
@Autowired
private EncryptorProperties properties;
@Bean
public EncryptorManager encryptorManager(MybatisPlusProperties mybatisPlusProperties) {
return new EncryptorManager(mybatisPlusProperties.getTypeAliasesPackage());
}
@Bean
public MybatisEncryptInterceptor mybatisEncryptInterceptor(EncryptorManager encryptorManager) {
return new MybatisEncryptInterceptor(encryptorManager, properties);
}
@Bean
public MybatisDecryptInterceptor mybatisDecryptInterceptor(EncryptorManager encryptorManager) {
return new MybatisDecryptInterceptor(encryptorManager, properties);
}
}

6
tp-common/src/main/java/com/inscloudtech/common/encrypt/EncryptContext.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/EncryptContext.java

@ -1,7 +1,7 @@
package com.inscloudtech.common.encrypt;
package com.inscloudtech.common.encrypt.core;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import lombok.Data;
/**

158
tp-common/src/main/java/com/inscloudtech/common/encrypt/core/EncryptorManager.java

@ -0,0 +1,158 @@
package com.inscloudtech.common.encrypt.core;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import com.inscloudtech.common.encrypt.annotation.EncryptField;
import com.inscloudtech.common.utils.StringUtils;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 加密管理类
*
* @author 老马
* @version 4.6.0
*/
@Slf4j
@NoArgsConstructor
public class EncryptorManager {
/**
* 缓存加密器
*/
Map<EncryptContext, IEncryptor> encryptorMap = new ConcurrentHashMap<>();
/**
* 类加密字段缓存
*/
Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>();
/**
* 构造方法传入类加密字段缓存
*
* @param typeAliasesPackage 实体类包
*/
public EncryptorManager(String typeAliasesPackage) {
scanEncryptClasses(typeAliasesPackage);
}
/**
* 获取类加密字段缓存
*/
public Set<Field> getFieldCache(Class<?> sourceClazz) {
if (ObjectUtil.isNotNull(fieldCache)) {
return fieldCache.get(sourceClazz);
}
return null;
}
/**
* 注册加密执行者到缓存
*
* @param encryptContext 加密执行者需要的相关配置参数
*/
public IEncryptor registAndGetEncryptor(EncryptContext encryptContext) {
if (encryptorMap.containsKey(encryptContext)) {
return encryptorMap.get(encryptContext);
}
IEncryptor encryptor = ReflectUtil.newInstance(encryptContext.getAlgorithm().getClazz(), encryptContext);
encryptorMap.put(encryptContext, encryptor);
return encryptor;
}
/**
* 移除缓存中的加密执行者
*
* @param encryptContext 加密执行者需要的相关配置参数
*/
public void removeEncryptor(EncryptContext encryptContext) {
this.encryptorMap.remove(encryptContext);
}
/**
* 根据配置进行加密会进行本地缓存对应的算法和对应的秘钥信息
*
* @param value 待加密的值
* @param encryptContext 加密相关的配置信息
*/
public String encrypt(String value, EncryptContext encryptContext) {
IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
return encryptor.encrypt(value, encryptContext.getEncode());
}
/**
* 根据配置进行解密
*
* @param value 待解密的值
* @param encryptContext 加密相关的配置信息
*/
public String decrypt(String value, EncryptContext encryptContext) {
IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
return encryptor.decrypt(value);
}
/**
* 通过 typeAliasesPackage 设置的扫描包 扫描缓存实体
*/
private void scanEncryptClasses(String typeAliasesPackage) {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
String[] packagePatternArray = StringUtils.splitPreserveAllTokens(typeAliasesPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
try {
for (String packagePattern : packagePatternArray) {
String path = ClassUtils.convertClassNameToResourcePath(packagePattern);
Resource[] resources = resolver.getResources(classpath + path + "/*.class");
for (Resource resource : resources) {
ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata();
Class<?> clazz = Resources.classForName(classMetadata.getClassName());
Set<Field> encryptFieldSet = getEncryptFieldSetFromClazz(clazz);
if (CollUtil.isNotEmpty(encryptFieldSet)) {
fieldCache.put(clazz, encryptFieldSet);
}
}
}
} catch (Exception e) {
log.error("初始化数据安全缓存时出错:{}", e.getMessage());
}
}
/**
* 获得一个类的加密字段集合
*/
private Set<Field> getEncryptFieldSetFromClazz(Class<?> clazz) {
Set<Field> fieldSet = new HashSet<>();
// 判断clazz如果是接口,内部类,匿名类就直接返回
if (clazz.isInterface() || clazz.isMemberClass() || clazz.isAnonymousClass()) {
return fieldSet;
}
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
fieldSet.addAll(Arrays.asList(fields));
clazz = clazz.getSuperclass();
}
fieldSet = fieldSet.stream().filter(field ->
field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
.collect(Collectors.toSet());
for (Field field : fieldSet) {
field.setAccessible(true);
}
return fieldSet;
}
}

6
tp-common/src/main/java/com/inscloudtech/common/encrypt/IEncryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/IEncryptor.java

@ -1,7 +1,7 @@
package com.inscloudtech.common.encrypt;
package com.inscloudtech.common.encrypt.core;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
/**
* 加解者

6
tp-common/src/main/java/com/inscloudtech/common/encrypt/encryptor/AbstractEncryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/AbstractEncryptor.java

@ -1,7 +1,7 @@
package com.inscloudtech.common.encrypt.encryptor;
package com.inscloudtech.common.encrypt.core.encryptor;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.encrypt.IEncryptor;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.core.IEncryptor;
/**
* 所有加密执行者的基类

10
tp-common/src/main/java/com/inscloudtech/common/encrypt/encryptor/AesEncryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/AesEncryptor.java

@ -1,9 +1,9 @@
package com.inscloudtech.common.encrypt.encryptor;
package com.inscloudtech.common.encrypt.core.encryptor;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
/**
* AES算法实现

11
tp-common/src/main/java/com/inscloudtech/common/encrypt/encryptor/Base64Encryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/Base64Encryptor.java

@ -1,9 +1,10 @@
package com.inscloudtech.common.encrypt.encryptor;
package com.inscloudtech.common.encrypt.core.encryptor;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.utils.EncryptUtils;
/**
* Base64算法实现

10
tp-common/src/main/java/com/inscloudtech/common/encrypt/encryptor/RsaEncryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/RsaEncryptor.java

@ -1,9 +1,9 @@
package com.inscloudtech.common.encrypt.encryptor;
package com.inscloudtech.common.encrypt.core.encryptor;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
import com.inscloudtech.common.utils.StringUtils;

11
tp-common/src/main/java/com/inscloudtech/common/encrypt/encryptor/Sm2Encryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/Sm2Encryptor.java

@ -1,10 +1,9 @@
package com.inscloudtech.common.encrypt.encryptor;
package com.inscloudtech.common.encrypt.core.encryptor;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
import com.inscloudtech.common.utils.StringUtils;
/**

10
tp-common/src/main/java/com/inscloudtech/common/encrypt/encryptor/Sm4Encryptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/core/encryptor/Sm4Encryptor.java

@ -1,9 +1,9 @@
package com.inscloudtech.common.encrypt.encryptor;
package com.inscloudtech.common.encrypt.core.encryptor;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
/**
* sm4算法实现

7
tp-common/src/main/java/com/inscloudtech/common/enums/AlgorithmType.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/enumd/AlgorithmType.java

@ -1,9 +1,10 @@
package com.inscloudtech.common.enums;
package com.inscloudtech.common.encrypt.enumd;
import com.inscloudtech.common.encrypt.encryptor.*;
import com.inscloudtech.common.encrypt.core.encryptor.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 算法名称
*
@ -17,7 +18,7 @@ public enum AlgorithmType {
/**
* 默认走yml配置
*/
DEFAULT(Base64Encryptor.class),
DEFAULT(null),
/**
* base64

2
tp-common/src/main/java/com/inscloudtech/common/enums/EncodeType.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/enumd/EncodeType.java

@ -1,4 +1,4 @@
package com.inscloudtech.common.enums;
package com.inscloudtech.common.encrypt.enumd;
/**
* 编码类型

16
tp-framework/src/main/java/com/inscloudtech/framework/filter/CryptoFilter.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/filter/CryptoFilter.java

@ -1,23 +1,28 @@
package com.inscloudtech.framework.filter;
package com.inscloudtech.common.encrypt.filter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import com.inscloudtech.common.constant.HttpStatus;
import com.inscloudtech.common.encrypt.annotation.ApiEncrypt;
import com.inscloudtech.common.encrypt.properties.ApiDecryptProperties;
import com.inscloudtech.common.exception.ServiceException;
import com.inscloudtech.common.utils.StringUtils;
import com.inscloudtech.common.utils.spring.SpringUtils;
import com.inscloudtech.framework.config.properties.ApiDecryptProperties;
import com.inscloudtech.framework.encrypt.ApiEncrypt;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
/**
@ -56,7 +61,7 @@ public class CryptoFilter implements Filter {
HandlerExceptionResolver exceptionResolver = SpringUtils.getBean("handlerExceptionResolver", HandlerExceptionResolver.class);
exceptionResolver.resolveException(
servletRequest, servletResponse, null,
new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN.value()));
new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN));
return;
}
}
@ -90,6 +95,7 @@ public class CryptoFilter implements Filter {
// 获取注解
try {
HandlerExecutionChain mappingHandler = handlerMapping.getHandler(servletRequest);
if (ObjectUtil.isNotNull(mappingHandler)) {
Object handler = mappingHandler.getHandler();
if (ObjectUtil.isNotNull(handler)) {

4
tp-framework/src/main/java/com/inscloudtech/framework/filter/DecryptRequestBodyWrapper.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/filter/DecryptRequestBodyWrapper.java

@ -1,9 +1,9 @@
package com.inscloudtech.framework.filter;
package com.inscloudtech.common.encrypt.filter;
import cn.hutool.core.io.IoUtil;
import com.inscloudtech.common.constant.Constants;
import com.inscloudtech.common.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
import org.springframework.http.MediaType;
import javax.servlet.ReadListener;

9
tp-framework/src/main/java/com/inscloudtech/framework/filter/EncryptResponseBodyWrapper.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/filter/EncryptResponseBodyWrapper.java

@ -1,17 +1,14 @@
package com.inscloudtech.framework.filter;
package com.inscloudtech.common.encrypt.filter;
import cn.hutool.core.util.RandomUtil;
import com.inscloudtech.common.utils.EncryptUtils;
import com.inscloudtech.common.encrypt.utils.EncryptUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**

30
tp-framework/src/main/java/com/inscloudtech/framework/encrypt/MybatisDecryptInterceptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/interceptor/MybatisDecryptInterceptor.java

@ -1,20 +1,21 @@
package com.inscloudtech.framework.encrypt;
package com.inscloudtech.common.encrypt.interceptor;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.inscloudtech.common.annotation.EncryptField;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.encrypt.annotation.EncryptField;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.core.EncryptorManager;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.properties.EncryptorProperties;
import com.inscloudtech.common.utils.StringUtils;
import com.inscloudtech.framework.config.properties.EncryptorProperties;
import com.inscloudtech.framework.manager.EncryptorManager;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.*;
@ -58,23 +59,28 @@ public class MybatisDecryptInterceptor implements Interceptor {
return;
}
if (sourceObject instanceof Map<?, ?>) {
new HashSet<>(((Map<?, ?>) sourceObject).values()).forEach(this::decryptHandler);
Map<?, ?> map = (Map<?, ?>)sourceObject;
new HashSet<>(map.values()).forEach(this::decryptHandler);
return;
}
if (sourceObject instanceof List<?>) {
List<?> sourceList = (List<?>) sourceObject;
if(CollUtil.isEmpty(sourceList)) {
List<?> list = (List<?>)sourceObject;
if(CollUtil.isEmpty(list)) {
return;
}
// 判断第一个元素是否含有注解如果没有直接返回提高效率
Object firstItem = sourceList.get(0);
Object firstItem = list.get(0);
if (ObjectUtil.isNull(firstItem) || CollUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) {
return;
}
((List<?>) sourceObject).forEach(this::decryptHandler);
list.forEach(this::decryptHandler);
return;
}
// 不在缓存中的类,就是没有加密注解的类(当然也有可能是typeAliasesPackage写错)
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
if(ObjectUtil.isNull(fields)){
return;
}
try {
for (Field field : fields) {
field.set(sourceObject, this.decryptField(Convert.toStr(field.get(sourceObject)), field));

32
tp-framework/src/main/java/com/inscloudtech/framework/encrypt/MybatisEncryptInterceptor.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/interceptor/MybatisEncryptInterceptor.java

@ -1,15 +1,15 @@
package com.inscloudtech.framework.encrypt;
package com.inscloudtech.common.encrypt.interceptor;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.inscloudtech.common.annotation.EncryptField;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.encrypt.annotation.EncryptField;
import com.inscloudtech.common.encrypt.core.EncryptContext;
import com.inscloudtech.common.encrypt.core.EncryptorManager;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import com.inscloudtech.common.encrypt.properties.EncryptorProperties;
import com.inscloudtech.common.utils.StringUtils;
import com.inscloudtech.framework.config.properties.EncryptorProperties;
import com.inscloudtech.framework.manager.EncryptorManager;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
@ -18,6 +18,7 @@ import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.util.*;
@ -49,7 +50,7 @@ public class MybatisEncryptInterceptor implements Interceptor {
public Object plugin(Object target) {
if (target instanceof ParameterHandler) {
// 进行加密操作
ParameterHandler parameterHandler = (ParameterHandler) target;
ParameterHandler parameterHandler = (ParameterHandler)target;
Object parameterObject = parameterHandler.getParameterObject();
if (ObjectUtil.isNotNull(parameterObject) && !(parameterObject instanceof String)) {
this.encryptHandler(parameterObject);
@ -68,23 +69,28 @@ public class MybatisEncryptInterceptor implements Interceptor {
return;
}
if (sourceObject instanceof Map<?, ?>) {
new HashSet<>(((Map<?, ?>) sourceObject).values()).forEach(this::encryptHandler);
Map<?, ?> map = (Map<?, ?>)sourceObject;
new HashSet<>(map.values()).forEach(this::encryptHandler);
return;
}
if (sourceObject instanceof List<?>) {
List<?> sourceList = (List<?>) sourceObject;
if(CollUtil.isEmpty(sourceList)) {
List<?> list = (List<?>)sourceObject;
if(CollUtil.isEmpty(list)) {
return;
}
// 判断第一个元素是否含有注解如果没有直接返回提高效率
Object firstItem = sourceList.get(0);
Object firstItem = list.get(0);
if (ObjectUtil.isNull(firstItem) || CollUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) {
return;
}
((List<?>) sourceObject).forEach(this::encryptHandler);
list.forEach(this::encryptHandler);
return;
}
// 不在缓存中的类,就是没有加密注解的类(当然也有可能是typeAliasesPackage写错)
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
if(ObjectUtil.isNull(fields)){
return;
}
try {
for (Field field : fields) {
field.set(sourceObject, this.encryptField(Convert.toStr(field.get(sourceObject)), field));

4
tp-framework/src/main/java/com/inscloudtech/framework/config/properties/ApiDecryptProperties.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/properties/ApiDecryptProperties.java

@ -1,15 +1,13 @@
package com.inscloudtech.framework.config.properties;
package com.inscloudtech.common.encrypt.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* api解密属性配置类
* @author wdhcr
*/
@Data
@Component
@ConfigurationProperties(prefix = "api-decrypt")
public class ApiDecryptProperties {

8
tp-framework/src/main/java/com/inscloudtech/framework/config/properties/EncryptorProperties.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/properties/EncryptorProperties.java

@ -1,10 +1,9 @@
package com.inscloudtech.framework.config.properties;
package com.inscloudtech.common.encrypt.properties;
import com.inscloudtech.common.enums.AlgorithmType;
import com.inscloudtech.common.enums.EncodeType;
import com.inscloudtech.common.encrypt.enumd.AlgorithmType;
import com.inscloudtech.common.encrypt.enumd.EncodeType;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 加解密属性配置类
@ -13,7 +12,6 @@ import org.springframework.stereotype.Component;
* @version 4.6.0
*/
@Data
@Component
@ConfigurationProperties(prefix = "mybatis-encryptor")
public class EncryptorProperties {

2
tp-common/src/main/java/com/inscloudtech/common/utils/EncryptUtils.java → tp-common/src/main/java/com/inscloudtech/common/encrypt/utils/EncryptUtils.java

@ -1,4 +1,4 @@
package com.inscloudtech.common.utils;
package com.inscloudtech.common.encrypt.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ArrayUtil;

1
tp-common/src/main/java/com/inscloudtech/common/filter/RepeatedlyRequestWrapper.java

@ -12,6 +12,7 @@ import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
/**
* 构建可重复读取inputStream的request

3
tp-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@ -0,0 +1,3 @@
com.inscloudtech.common.encrypt.config.EncryptorAutoConfiguration
com.inscloudtech.common.encrypt.config.ApiDecryptAutoConfiguration

39
tp-framework/src/main/java/com/inscloudtech/framework/config/EncryptorConfig.java

@ -1,39 +0,0 @@
package com.inscloudtech.framework.config;
import com.inscloudtech.framework.config.properties.EncryptorProperties;
import com.inscloudtech.framework.manager.EncryptorManager;
import com.inscloudtech.framework.encrypt.MybatisDecryptInterceptor;
import com.inscloudtech.framework.encrypt.MybatisEncryptInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 加解密配置
*
* @author 老马
* @version 4.6.0
*/
@Configuration
@ConditionalOnProperty(value = "mybatis-encryptor.enable", havingValue = "true")
public class EncryptorConfig {
@Autowired
private EncryptorProperties properties;
@Bean
public EncryptorManager encryptorManager() {
return new EncryptorManager();
}
@Bean
public MybatisEncryptInterceptor mybatisEncryptInterceptor(EncryptorManager encryptorManager) {
return new MybatisEncryptInterceptor(encryptorManager, properties);
}
@Bean
public MybatisDecryptInterceptor mybatisDecryptInterceptor(EncryptorManager encryptorManager) {
return new MybatisDecryptInterceptor(encryptorManager, properties);
}
}

18
tp-framework/src/main/java/com/inscloudtech/framework/handler/AllUrlHandler.java

@ -1,13 +1,17 @@
package com.inscloudtech.framework.handler;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.inscloudtech.common.utils.spring.SpringUtils;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;
import java.util.*;
import java.util.regex.Pattern;
@ -32,10 +36,20 @@ public class AllUrlHandler implements InitializingBean {
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
map.keySet().forEach(info -> {
// 获取注解上边的 path 替代 path variable *
Objects.requireNonNull(info.getPathPatternsCondition().getPatterns())
.forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*")));
try {
PatternsRequestCondition patternsCondition = info.getPatternsCondition();
if(CollectionUtil.isNotEmpty(patternsCondition.getPatterns())){
for (String url : patternsCondition.getPatterns()) {
set.add(ReUtil.replaceAll(url, PATTERN, "*"));
}
}
}catch (Exception e){
e.printStackTrace();
}
});
urls.addAll(set);
}
}

96
tp-framework/src/main/java/com/inscloudtech/framework/manager/EncryptorManager.java

@ -1,96 +0,0 @@
package com.inscloudtech.framework.manager;
import cn.hutool.core.util.ReflectUtil;
import com.inscloudtech.common.annotation.EncryptField;
import com.inscloudtech.common.encrypt.EncryptContext;
import com.inscloudtech.common.encrypt.IEncryptor;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 加密管理类
*
* @author 老马
* @version 4.6.0
*/
@Slf4j
public class EncryptorManager {
/**
* 缓存加密器
*/
Map<EncryptContext, IEncryptor> encryptorMap = new ConcurrentHashMap<>();
/**
* 类加密字段缓存
*/
Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>();
/**
* 获取类加密字段缓存
*/
public Set<Field> getFieldCache(Class<?> sourceClazz) {
return fieldCache.computeIfAbsent(sourceClazz, clazz -> {
Field[] declaredFields = clazz.getDeclaredFields();
Set<Field> fieldSet = Arrays.stream(declaredFields).filter(field ->
field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
.collect(Collectors.toSet());
for (Field field : fieldSet) {
field.setAccessible(true);
}
return fieldSet;
});
}
/**
* 注册加密执行者到缓存
*
* @param encryptContext 加密执行者需要的相关配置参数
*/
public IEncryptor registAndGetEncryptor(EncryptContext encryptContext) {
if (encryptorMap.containsKey(encryptContext)) {
return encryptorMap.get(encryptContext);
}
IEncryptor encryptor = ReflectUtil.newInstance(encryptContext.getAlgorithm().getClazz(), encryptContext);
encryptorMap.put(encryptContext, encryptor);
return encryptor;
}
/**
* 移除缓存中的加密执行者
*
* @param encryptContext 加密执行者需要的相关配置参数
*/
public void removeEncryptor(EncryptContext encryptContext) {
this.encryptorMap.remove(encryptContext);
}
/**
* 根据配置进行加密会进行本地缓存对应的算法和对应的秘钥信息
*
* @param value 待加密的值
* @param encryptContext 加密相关的配置信息
*/
public String encrypt(String value, EncryptContext encryptContext) {
IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
return encryptor.encrypt(value, encryptContext.getEncode());
}
/**
* 根据配置进行解密
*
* @param value 待解密的值
* @param encryptContext 加密相关的配置信息
*/
public String decrypt(String value, EncryptContext encryptContext) {
IEncryptor encryptor = this.registAndGetEncryptor(encryptContext);
return encryptor.decrypt(value);
}
}

72
tp-functional/src/test/java/JvmMemoryTest.java

@ -0,0 +1,72 @@
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class JvmMemoryTest {
//声明缓存对象
private static final Map map = new HashMap();
public static void main(String args[]){
try {
Thread.sleep(100000);//给打开visualvm时间
} catch (InterruptedException e) {
e.printStackTrace();
}
//循环添加对象到缓存
for(int i=0; i<1000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("first");
//为dump出堆提供时间
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<1000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("second");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<3000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("third");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<4000000;i++){
TestMemory t = new TestMemory();
map.put("key"+i,t);
}
System.out.println("forth");
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("qqqq");
}
}
/**
*
*/
class TestMemory {
}
Loading…
Cancel
Save