feat: update

This commit is contained in:
zlg
2024-05-26 17:17:49 +08:00
parent c3a29cedca
commit 1154a53e9f
34 changed files with 956 additions and 223 deletions

View File

@@ -0,0 +1,67 @@
package com.schisandra.oss.application.aspect;
import com.schisandra.oss.application.dto.SchisandraOssMinioDTO;
import com.schisandra.oss.common.redis.RedisUtil;
import com.schisandra.oss.common.utils.AESUtils;
import com.schisandra.oss.common.utils.RSAUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Slf4j
@Aspect
@Component
public class DecryptAspect {
@Autowired
RedisUtil redisUtil;
private final String authSecretKeyPrefix = "auth.SecretKey";
/**
* @description: 解密切面
* @param: []
* @return: void
* @author zlg
* @date: 2024/5/23 19:53
*/
@Pointcut("@annotation(com.schisandra.oss.application.aspect.NeedDecrypt)")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//解密
Object result = decrypt(joinPoint);
return result;
}
public Object decrypt(ProceedingJoinPoint joinPoint) {
Object result = null;
Object []objects=null;
try {
objects = joinPoint.getArgs();
Object obj = joinPoint.proceed();
SchisandraOssMinioDTO schisandraOssMinioDTO=(SchisandraOssMinioDTO) obj;
String prefix = redisUtil.buildKey(authSecretKeyPrefix, String.valueOf(objects[0]));
if (obj!= null) {
HashMap<String,String> map=redisUtil.getJson(prefix);
String key=RSAUtils.decryptByPrivate(map.get("AESKey"),map.get("privateKey"));
// AESUtils.decrypt(objects.toString(),key);
// schisandraOssMinioDTO.setUserId(Long.valueOf(AESUtils.decrypt(String.valueOf(schisandraOssMinioDTO.getUserId()),key)));
schisandraOssMinioDTO.setEndpoint(AESUtils.decrypt(schisandraOssMinioDTO.getEndpoint(),key));
schisandraOssMinioDTO.setSecretKey(AESUtils.decrypt(schisandraOssMinioDTO.getSecretKey(),key));
schisandraOssMinioDTO.setAccessKey(AESUtils.decrypt(schisandraOssMinioDTO.getAccessKey(),key));
result=schisandraOssMinioDTO;
}
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
}

View File

@@ -0,0 +1,62 @@
package com.schisandra.oss.application.aspect;
import com.schisandra.oss.application.dto.SchisandraOssMinioDTO;
import com.schisandra.oss.common.redis.RedisUtil;
import com.schisandra.oss.common.utils.AESUtils;
import com.schisandra.oss.common.utils.RSAUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Aspect
@Component
public class EncryptAspect {
@Autowired
private RedisUtil redisUtil;
private final String authSecretKeyPrefix = "auth.SecretKey";
@Pointcut("@annotation(com.schisandra.oss.application.aspect.NeedEncrypt)")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//加密
encrypt(joinPoint);
return joinPoint.proceed();
}
public void encrypt(ProceedingJoinPoint joinPoint) {
Object[] objects = null;
try {
objects = joinPoint.getArgs();
SchisandraOssMinioDTO schisandraOssMinioDTO= (SchisandraOssMinioDTO) objects[0];
String prefix = redisUtil.buildKey(authSecretKeyPrefix, String.valueOf(schisandraOssMinioDTO.getUserId()));
String key = AESUtils.getKey();
Map<String, String> map = new HashMap<>();
map = RSAUtils.getPriKeyAndPubKey();
String publicKey = map.get("publicKey");
if (objects.length != 0) {
schisandraOssMinioDTO.setEndpoint(AESUtils.encrypt(schisandraOssMinioDTO.getEndpoint(), key));
schisandraOssMinioDTO.setSecretKey(AESUtils.encrypt(schisandraOssMinioDTO.getSecretKey(), key));
schisandraOssMinioDTO.setAccessKey(AESUtils.encrypt(schisandraOssMinioDTO.getAccessKey(), key));
objects[0] = schisandraOssMinioDTO;
String AESkey = RSAUtils.encryptByPublic(key, publicKey);
map.put("AESKey", AESkey);
redisUtil.setJson(prefix, map);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,11 @@
package com.schisandra.oss.application.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptField {
}

View File

@@ -0,0 +1,11 @@
package com.schisandra.oss.application.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedDecrypt {
}

View File

@@ -0,0 +1,11 @@
package com.schisandra.oss.application.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedEncrypt {
}

View File

@@ -3,6 +3,8 @@ package com.schisandra.oss.application.controller;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.schisandra.oss.application.aspect.NeedDecrypt;
import com.schisandra.oss.application.aspect.NeedEncrypt;
import com.schisandra.oss.application.convert.SchisandraOssMinioDTOConverter;
import com.schisandra.oss.application.dto.SchisandraOssMinioDTO;
import com.schisandra.oss.application.oss.core.minio.MinioOssClient;
@@ -27,6 +29,8 @@ import java.util.List;
@RequestMapping("/oss/minio/")
@Slf4j
public class SchisandraOssMinioController {
@Resource
MinioOssClient minioOssClient;
@Resource
private SchisandraOssMinioDomainService schisandraOssMinioDomainService;
@@ -47,6 +51,7 @@ public class SchisandraOssMinioController {
*/
@PostMapping("init")
public void initMinio(@RequestParam String userId) {
if (log.isInfoEnabled()) {
log.info("SchisandraOssMinioController.init.userId:{}", userId);
}
@@ -60,24 +65,29 @@ public class SchisandraOssMinioController {
}
minioOssConfiguration.minioOssClient(userId);
log.info("用户: " + userId + "-> minio 初始化完成!");
redisUtil.set(key, "true");
} catch (Exception e) {
log.error("用户: " + userId + "-> minio 初始化失败!", e.getMessage(), e);
}
}
@NeedDecrypt
@PostMapping("get")
public SchisandraOssMinioDTO getMinioOss(@RequestParam String userId) {
return SchisandraOssMinioDTOConverter.INSTANCE.convertBOToDTO(schisandraOssMinioDomainService.getMinioConfig(Long.valueOf(userId)));
}
/**
* 新增
*/
@PostMapping("add")
@NeedEncrypt
@RequestMapping("add")
public Result<Boolean> addMinioOss(@RequestBody SchisandraOssMinioDTO schisandraOssMinioDTO) {
try {
if (log.isInfoEnabled()) {
log.info("SchisandraOssMinioController.add.dto:{}", JSON.toJSONString(schisandraOssMinioDTO));
}
parameterCheck(schisandraOssMinioDTO);
// parameterCheck(schisandraOssMinioDTO);
SchisandraOssMinioBO SchisandraOssMinioBO = SchisandraOssMinioDTOConverter.INSTANCE.convertDTOToBO(schisandraOssMinioDTO);
return Result.ok(schisandraOssMinioDomainService.add(SchisandraOssMinioBO));
} catch (Exception e) {
@@ -92,6 +102,7 @@ public class SchisandraOssMinioController {
*/
@PostMapping("update")
public Result<Boolean> updateMinioOss(@RequestBody SchisandraOssMinioDTO schisandraOssMinioDTO) {
try {
if (log.isInfoEnabled()) {
log.info("SchisandraOssMinioController.update.dto:{}", JSON.toJSONString(schisandraOssMinioDTO));

View File

@@ -1,5 +1,6 @@
package com.schisandra.oss.application.dto;
import com.schisandra.oss.application.aspect.EncryptField;
import lombok.Data;
import java.io.Serializable;
@@ -22,21 +23,25 @@ public class SchisandraOssMinioDTO implements Serializable {
/**
*
*/
@EncryptField
private Long userId;
/**
*
*/
@EncryptField
private String endpoint;
/**
*
*/
@EncryptField
private String accessKey;
/**
*
*/
@EncryptField
private String secretKey;
/**

View File

@@ -1,6 +1,7 @@
package com.schisandra.oss.application.oss.core.minio;
import cn.hutool.extra.spring.SpringUtil;
import com.schisandra.oss.application.aspect.NeedDecrypt;
import com.schisandra.oss.application.convert.SchisandraOssMinioDTOConverter;
import com.schisandra.oss.application.dto.SchisandraOssMinioDTO;
import com.schisandra.oss.application.oss.core.StandardOssClient;
@@ -13,7 +14,6 @@ import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.ObjectUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -31,12 +31,14 @@ public class MinioOssConfiguration {
@Resource
private RedisUtil redisUtil;
@Resource
MinioOssConfiguration minioOssConfiguration;
@Resource
private SchisandraOssMinioDomainService schisandraOssMinioDomainService;
public StandardOssClient minioOssClient(String userId) {
SchisandraOssMinioDTO minio = getSchisandraOssMinioDTO(userId);
SchisandraOssMinioDTO minio = minioOssConfiguration.getSchisandraOssMinioDTO(userId);
if (minio == null) return null;
MinioOssConfig minioOssConfig = new MinioOssConfig();
minioOssConfig.setBasePath(minio.getBasePath());
@@ -63,8 +65,10 @@ public class MinioOssConfiguration {
}
@Nullable
private SchisandraOssMinioDTO getSchisandraOssMinioDTO(String userId) {
@NeedDecrypt
public SchisandraOssMinioDTO getSchisandraOssMinioDTO(String userId) {
CompletableFuture<SchisandraOssMinioDTO> futurePrice = CompletableFuture.supplyAsync(() -> {
SchisandraOssMinioBO minioBO = schisandraOssMinioDomainService.getMinioConfig(Long.valueOf(userId));
SchisandraOssMinioDTO minioDTO = SchisandraOssMinioDTOConverter.INSTANCE.convertBOToDTO(minioBO);

View File

@@ -1,10 +1,12 @@
package com.schisandra.oss.common.redis;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -53,6 +55,14 @@ public class RedisUtil {
redisTemplate.opsForValue().set(key, value);
}
public void setJson(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
public HashMap<String, String> getJson(String key) {
return (HashMap<String, String>) redisTemplate.opsForValue().get(key);
}
/**
* set(带过期)
*/

View File

@@ -1,19 +1,13 @@
package com.schisandra.oss.common.utils;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.HashMap;
/**
* @ClassName RSAUtils
@@ -24,149 +18,68 @@ import java.util.Map;
public class RSAUtils {
/**
* 加密算法RSA
* 公钥加密(解密就要用到对应的私钥)
*
* @param msg 明文信息
* @param pubKey 公钥,用来加密明文
* @return
*/
private static final String KEY_ALGORITHM = "RSA";
/**
* 算法名称/加密模式/数据填充方式
* 默认RSA/ECB/PKCS1Padding
*/
private static final String ALGORITHMS = "RSA/ECB/PKCS1Padding";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 245;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 256;
/**
* RSA 位数 如果采用2048 上面最大加密和最大解密则须填写: 245 256
*/
private static final int INITIALIZE_LENGTH = 2048;
/**
* 后端RSA的密钥对(公钥和私钥)Map由静态代码块赋值
*/
private static final Map<String, String> map = new LinkedHashMap<>(2);
/**
* 生成密钥对(公钥和私钥)
*/
public static Map<String,String> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(INITIALIZE_LENGTH);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 获取公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 获取私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥字符串
String publicKeyString = Base64.encodeBase64String(publicKey.getEncoded());
// 得到私钥字符串
String privateKeyString = Base64.encodeBase64String((privateKey.getEncoded()));
map.put("publicKey",publicKeyString);
map.put("privateKey",privateKeyString);
return map;
}
public static String getPrivateKey(){
return map.get("privateKey");
}
public static String getPublicKey(){
return map.get("publicKey");
}
/**
* RSA私钥解密
* @param data BASE64编码过的密文
* @param privateKey 私钥(BASE64编码)
* @return utf-8编码的明文
*/
public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
//base64格式的key字符串转Key对象
Key privateK = KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));
Cipher cipher = Cipher.getInstance(ALGORITHMS);
cipher.init(Cipher.DECRYPT_MODE, privateK);
//分段进行解密操作
return encryptAndDecryptOfSubsection(data, cipher, MAX_DECRYPT_BLOCK);
public static String encryptByPublic(String msg, String pubKey) {
RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), null, pubKey);
return rsa.encryptBase64(msg, KeyType.PublicKey);
}
/**
* RSA公钥加
* @param data BASE64编码过的密文
* @param publicKey 公钥(BASE64编码)
* @return utf-8编码的明
* 私钥解
*
* @param encryptMsg 公钥加密的密文
* @param priKey 私钥,用来解密密
* @return
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
//base64格式的key字符串转Key对象
Key publicK = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey)));
Cipher cipher = Cipher.getInstance(ALGORITHMS);
cipher.init(Cipher.ENCRYPT_MODE, publicK);
//分段进行加密操作
return encryptAndDecryptOfSubsection(data, cipher, MAX_ENCRYPT_BLOCK);
public static String decryptByPrivate(String encryptMsg, String priKey) {
RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), priKey, null);
return rsa.decryptStr(encryptMsg, KeyType.PrivateKey);
}
/**
* RSA公钥解密
* @param data BASE64编码过的密文
* @param publicKey RSA公钥
* @return utf-8编码的明文
* 私钥加密(解密就要用到对应的公钥)
*
* @param msg 明文信息
* @param priKey 私钥,用来加密明文
* @return
*/
public static byte[] pubKeyDec(byte[] data, String publicKey) throws Exception {
//base64格式的key字符串转Key对象
Key privateK = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey)));
Cipher cipher = Cipher.getInstance(ALGORITHMS);
cipher.init(Cipher.DECRYPT_MODE, privateK);
//分段进行解密操作
return encryptAndDecryptOfSubsection(data, cipher, MAX_DECRYPT_BLOCK);
public static String encryptByPrivate(String msg, String priKey) {
RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), priKey, null);
return rsa.encryptBase64(msg, KeyType.PrivateKey);
}
/**
* RSA私钥加
* @param data 待加密的明文
* @param privateKey RSA私钥
* @return 经BASE64编码后的密文
* 公钥解
*
* @param encryptMsg 密文
* @param pubKey 公钥,用来解密
* @return
*/
public static byte[] privKeyEnc(byte[] data, String privateKey) throws Exception {
//base64格式的key字符串转Key对象
Key publicK = KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));
Cipher cipher = Cipher.getInstance(ALGORITHMS);
cipher.init(Cipher.ENCRYPT_MODE, publicK);
//分段进行加密操作
return encryptAndDecryptOfSubsection(data, cipher, MAX_ENCRYPT_BLOCK);
public static String decryptByPublic(String encryptMsg, String pubKey) {
RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), null, pubKey);
return rsa.decryptStr(encryptMsg, KeyType.PublicKey);
}
/**
* 分段进行加密、解密操作
* 获取公私钥集合
*
* @return
*/
private static byte[] encryptAndDecryptOfSubsection(byte[] data, Cipher cipher, int encryptBlock) throws Exception {
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > encryptBlock) {
cache = cipher.doFinal(data, offSet, encryptBlock);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * encryptBlock;
}
out.close();
return out.toByteArray();
public static HashMap<String,String> getPriKeyAndPubKey() {
KeyPair pair = SecureUtil.generateKeyPair("RSA");
String privateKey = Base64.encodeBase64String(pair.getPrivate().getEncoded());
String publicKey = Base64.encodeBase64String(pair.getPublic().getEncoded());
HashMap<String,String> keys = new HashMap<>();
keys.put("privateKey",privateKey);
keys.put("publicKey",publicKey);
return keys;
}
}

View File

@@ -49,5 +49,13 @@
<artifactId>schisandra-cloud-storage-oss-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
</project>

View File

@@ -13,6 +13,7 @@ import java.util.List;
*/
public interface SchisandraOssMinioService {
/**
* 通过ID查询单条数据
*

View File

@@ -3,10 +3,11 @@ package com.schisandra.oss.infra.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.schisandra.oss.infra.basic.dao.SchisandraOssMinioDao;
import com.schisandra.oss.infra.basic.entity.SchisandraOssMinio;
import com.schisandra.oss.infra.basic.service.SchisandraOssMinioService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -20,7 +21,10 @@ import java.util.Objects;
* @since 2024-05-14 19:47:04
*/
@Service("SchisandraOssMinioService")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SchisandraOssMinioServiceImpl implements SchisandraOssMinioService {
@Autowired
SchisandraOssMinioServiceImpl schisandraOssMinioService;
@Resource
private SchisandraOssMinioDao schisandraOssMinioDao;
@@ -55,7 +59,14 @@ public class SchisandraOssMinioServiceImpl implements SchisandraOssMinioService
*/
@Override
public int update(SchisandraOssMinio schisandraOssMinio) {
// ApplicationContext applicationContext=null;
// Service service=applicationContext.getBean(Service.class);
// final SchisandraOssMinioService bean=context.getBean(SchisandraOssMinioService.class);
// return bean.update(schisandraOssMinio);
return this.schisandraOssMinioDao.updateById(schisandraOssMinio);
// eById(schisandraOssMinio);
// return schisandraOssMinioDao.update(schisandraOssMinio);
}
/**

View File

@@ -4,6 +4,7 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* 存储微服务启动类
@@ -14,6 +15,7 @@ import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.schisandra")
@MapperScan("com.schisandra.**.dao")
public class OssApplication {
public static void main(String[] args) {
SpringApplication.run(OssApplication.class);