new
This commit is contained in:
@@ -7,6 +7,8 @@ stages:
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- sudo docker rm -f nacos
|
||||
- sudo docker run -d --name nacos --network mynetwork -p 8849:8848 -e MODE=standalone nacos/nacos-server:2.0.2
|
||||
- mvn clean package
|
||||
- sudo docker build -t library-service ./library
|
||||
- sudo docker build -t gateway-service ./gateway
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>security-api-demo</artifactId>
|
||||
<groupId>org.example</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>common</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!--lombok-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.10</version>
|
||||
</dependency>
|
||||
<!--commons-langs-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.11</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.2</version>
|
||||
</dependency>
|
||||
<!--json-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.73</version>
|
||||
</dependency>
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.15</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<!--日志-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.demo.constant;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @Author: Rosh
|
||||
* @Date: 2021/10/27 09:53
|
||||
*/
|
||||
public final class RSAConstant {
|
||||
|
||||
private RSAConstant(){
|
||||
|
||||
}
|
||||
public static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFtTlL61IqIGd+fRLUhJ0MjsqFXFJswCohJ45m51WvbxDPRP3gllW0WChk74D5JEOpMDSWo4C7RfoGlBRNW7kQ6qYGukYZ5jgYpzoT0+gp3on96fQXEyQJysv9xiTPIdmSXXVVj1HAOJw29RbzxIVKUSzzPXvEtXRTtCC1+wkAJQIDAQAB";
|
||||
|
||||
public static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIW1OUvrUiogZ359EtSEnQyOyoVcUmzAKiEnjmbnVa9vEM9E/eCWVbRYKGTvgPkkQ6kwNJajgLtF+gaUFE1buRDqpga6RhnmOBinOhPT6Cneif3p9BcTJAnKy/3GJM8h2ZJddVWPUcA4nDb1FvPEhUpRLPM9e8S1dFO0ILX7CQAlAgMBAAECgYBC4amtbiKFa/wY61tV7pfYRjzLhKi+OUlZmD3E/4Z+4KGZ7DrJ8qkgMtDR3HO5LAikQrare1HTW2d7juqw32ascu+uDObf4yrYNKin+ZDLUYvIDfLhThPxnZJwQ/trdtfxO3VM//XbwZacmwYbAsYW/3QPUXwwOPAgbC2oth8kqQJBANKLyXcdjZx4cwJVl7xNeC847su8y6bPpcBASsaQloCIPiNBIg1h76dpfEGIQBYWJWbBsxtHe/MhOmz7fNFDS2sCQQCiktYZR0dZNH4eNX329LoRuBiltpr9tf36rVOlKr1GSHkLYEHF2qtyXV2mdrY8ZWpvuo3qm1oSLaqmop2rN9avAkBHk85B+IIUF77BpGeZVJzvMOO9z8lMRHuNCE5jgvQnbinxwkrZUdovh+T+QlvHJnBApslFFOBGn51FP5oHamFRAkEAmwZmPsinkrrpoKjlqz6GyCrC5hKRDWoj/IyXfKKaxpCJTH3HeoIghvfdO8Vr1X/n1Q8SESt+4mLFngznSMQAZQJBAJx07bCFYbA2IocfFV5LTEYTIiUeKdue2NP2yWqZ/+tB5H7jNwQTJmX1mn0W/sZm4+nJM7SjfETpNZhH49+rV6U=";
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.demo.constant;
|
||||
|
||||
public class UserConstant {
|
||||
|
||||
private UserConstant() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final String TOKEN = "token";
|
||||
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.demo.excepiton;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @Author: Rosh
|
||||
* @Date: 2021/8/10 17:39
|
||||
*/
|
||||
@Getter
|
||||
public class RSAException extends RuntimeException {
|
||||
|
||||
private final String message;
|
||||
|
||||
|
||||
public RSAException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.demo.utils;
|
||||
|
||||
import com.demo.excepiton.RSAException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class RSAUtils {
|
||||
|
||||
public static final String PUBLIC_KEY = "public_key";
|
||||
|
||||
public static final String PRIVATE_KEY = "private_key";
|
||||
|
||||
|
||||
public static Map<String, String> generateRasKey() {
|
||||
Map<String, String> rs = new HashMap<>();
|
||||
try {
|
||||
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
|
||||
KeyPairGenerator keyPairGen = null;
|
||||
keyPairGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGen.initialize(1024, new SecureRandom());
|
||||
// 生成一个密钥对,保存在keyPair中
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
// 得到私钥 公钥
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
|
||||
// 得到私钥字符串
|
||||
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
|
||||
// 将公钥和私钥保存到Map
|
||||
rs.put(PUBLIC_KEY, publicKeyString);
|
||||
rs.put(PRIVATE_KEY, privateKeyString);
|
||||
} catch (Exception e) {
|
||||
throw new RSAException("RsaUtils invoke genKeyPair failed.");
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
public static String encrypt(String str, String publicKey) {
|
||||
try {
|
||||
//base64编码的公钥
|
||||
byte[] decoded = Base64.decodeBase64(publicKey);
|
||||
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
|
||||
//RSA加密
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
|
||||
return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
|
||||
} catch (Exception e) {
|
||||
throw new RSAException("RsaUtils invoke encrypt failed.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String decrypt(String str, String privateKey) {
|
||||
|
||||
try {
|
||||
//64位解码加密后的字符串
|
||||
byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
|
||||
//base64编码的私钥
|
||||
byte[] decoded = Base64.decodeBase64(privateKey);
|
||||
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
|
||||
//RSA解密
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, priKey);
|
||||
return new String(cipher.doFinal(inputByte));
|
||||
} catch (Exception e) {
|
||||
throw new RSAException("RsaUtils invoke decrypt failed.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package com.demo.utils;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtBuilder;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @Author: Rosh
|
||||
* @Date: 2021/8/11 14:21
|
||||
*/
|
||||
public final class TokenUtils {
|
||||
|
||||
|
||||
private static final String SIGN_KEY = "STREAM_TOKEN";
|
||||
|
||||
|
||||
/**
|
||||
*jwt 有效期为3天
|
||||
*/
|
||||
private static final Long JWT_EXPIRE_TIME_LONG = 1000 * 60 * 60 * 24 * 3L;
|
||||
|
||||
|
||||
private TokenUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static String createToken(String str) {
|
||||
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
|
||||
long nowMillis = System.currentTimeMillis();
|
||||
Date now = new Date(nowMillis);
|
||||
SecretKey secretKey = createSecretKey();
|
||||
|
||||
JwtBuilder builder = Jwts.builder()
|
||||
.setId(UUID.randomUUID().toString())
|
||||
.setIssuedAt(now)
|
||||
.setSubject(str)
|
||||
.signWith(signatureAlgorithm, secretKey);
|
||||
|
||||
long expMillis = System.currentTimeMillis() + JWT_EXPIRE_TIME_LONG;
|
||||
Date exp = new Date(expMillis);
|
||||
|
||||
//token过期时间
|
||||
builder.setExpiration(exp);
|
||||
|
||||
return builder.compact();
|
||||
}
|
||||
|
||||
private static SecretKey createSecretKey() {
|
||||
byte[] encodedKey = Base64.decodeBase64(SIGN_KEY);
|
||||
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
|
||||
}
|
||||
|
||||
|
||||
public static Claims getClaim(String token) {
|
||||
SecretKey secretKey = createSecretKey();
|
||||
try {
|
||||
return Jwts.parser()
|
||||
.setSigningKey(secretKey)
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package com.common;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RSAEncrypt {
|
||||
private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); //用于封装随机产生的公钥与私钥
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("username", "rosh");
|
||||
jsonObject.put("password", "123456");
|
||||
|
||||
//生成公钥和私钥
|
||||
genKeyPair();
|
||||
//加密字符串
|
||||
String message = jsonObject.toJSONString();
|
||||
System.out.println("随机生成的公钥为:" + keyMap.get(0));
|
||||
System.out.println("随机生成的私钥为:" + keyMap.get(1));
|
||||
String messageEn = encrypt(message,keyMap.get(0));
|
||||
System.out.println(message + "\t加密后的字符串为:" + messageEn);
|
||||
String messageDe = decrypt(messageEn,keyMap.get(1));
|
||||
System.out.println("还原后的字符串为:" + messageDe);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成密钥对
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static void genKeyPair() throws NoSuchAlgorithmException {
|
||||
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
|
||||
// 初始化密钥对生成器,密钥大小为96-1024位
|
||||
keyPairGen.initialize(1024,new SecureRandom());
|
||||
// 生成一个密钥对,保存在keyPair中
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
|
||||
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
|
||||
// 得到私钥字符串
|
||||
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
|
||||
// 将公钥和私钥保存到Map
|
||||
keyMap.put(0,publicKeyString); //0表示公钥
|
||||
keyMap.put(1,privateKeyString); //1表示私钥
|
||||
}
|
||||
/**
|
||||
* RSA公钥加密
|
||||
*
|
||||
* @param str
|
||||
* 加密字符串
|
||||
* @param publicKey
|
||||
* 公钥
|
||||
* @return 密文
|
||||
* @throws Exception
|
||||
* 加密过程中的异常信息
|
||||
*/
|
||||
public static String encrypt( String str, String publicKey ) throws Exception{
|
||||
//base64编码的公钥
|
||||
byte[] decoded = Base64.decodeBase64(publicKey);
|
||||
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
|
||||
//RSA加密
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
|
||||
String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
|
||||
return outStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* RSA私钥解密
|
||||
*
|
||||
* @param str
|
||||
* 加密字符串
|
||||
* @param privateKey
|
||||
* 私钥
|
||||
* @return 铭文
|
||||
* @throws Exception
|
||||
* 解密过程中的异常信息
|
||||
*/
|
||||
public static String decrypt(String str, String privateKey) throws Exception{
|
||||
//64位解码加密后的字符串
|
||||
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
|
||||
//base64编码的私钥
|
||||
byte[] decoded = Base64.decodeBase64(privateKey);
|
||||
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
|
||||
//RSA解密
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, priKey);
|
||||
String outStr = new String(cipher.doFinal(inputByte));
|
||||
return outStr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.common;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @Author: rosh
|
||||
* @Date: 2021/10/25 23:32
|
||||
*/
|
||||
public class test {
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,14 +13,7 @@ services:
|
||||
image: redis:latest
|
||||
networks:
|
||||
- mynetwork
|
||||
nacos:
|
||||
image: nacos/nacos-server:2.0.2
|
||||
networks:
|
||||
- mynetwork
|
||||
ports:
|
||||
- "8849:8848"
|
||||
environment:
|
||||
MODE: "standalone"
|
||||
|
||||
|
||||
|
||||
library:
|
||||
|
||||
@@ -29,13 +29,22 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--依赖common-->
|
||||
<dependency>
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.7</version> <!-- 版本号根据你的需求进行调整 -->
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.demo.gateway.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface LoggableGlobalFilter {
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.demo.gateway.config;
|
||||
|
||||
import com.demo.gateway.annotations.LoggableGlobalFilter;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class GlobalFilterLoggingAspect {
|
||||
|
||||
private Logger logger = LogManager.getLogger(GlobalFilterLoggingAspect.class);
|
||||
|
||||
@Before("@within(loggableGlobalFilter) && execution(public * org.springframework.web.server.WebFilter.filter(..)) && args(exchange)")
|
||||
public void logGlobalFilterExecution(LoggableGlobalFilter loggableGlobalFilter, ServerWebExchange exchange) {
|
||||
Class<?> filterClass = loggableGlobalFilter.getClass();
|
||||
logger.info("Executing global filter: " + filterClass.getName() + " for request: " + exchange.getRequest().getURI());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.demo.gateway.exception;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -22,7 +21,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Slf4j
|
||||
|
||||
public class GatewayExceptionHandler extends AbstractExceptionHandler implements ErrorWebExceptionHandler {
|
||||
|
||||
|
||||
|
||||
@@ -3,10 +3,13 @@ package com.demo.gateway.filter;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.common.utils.Md5Utils;
|
||||
import com.demo.gateway.annotations.LoggableGlobalFilter;
|
||||
import com.demo.gateway.config.FilterUtils;
|
||||
import com.demo.gateway.pojo.MyCachedBodyOutputMessage;
|
||||
import com.demo.gateway.utils.AESUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
@@ -49,6 +52,7 @@ public class RequestEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
private static final Logger log = LogManager.getLogger();
|
||||
|
||||
private static final String ERROR_MESSAGE = "拒绝服务";
|
||||
private static final String SIGN_ERROR_MESSAGE = "签名过期";
|
||||
@@ -57,7 +61,7 @@ public class RequestEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
//拦截OPTIONS请求
|
||||
|
||||
log.debug("1. 获取请求头");
|
||||
//1 获取时间戳
|
||||
Long dateTimestamp = getDateTimestamp(exchange.getRequest().getHeaders());
|
||||
//2 获取RequestId
|
||||
@@ -75,12 +79,14 @@ public class RequestEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
// }
|
||||
// }
|
||||
//5 修改请求参数,并获取请求参数
|
||||
|
||||
Map<String, Object> paramMap;
|
||||
try {
|
||||
paramMap = updateRequestParam(exchange);
|
||||
} catch (Exception e) {
|
||||
return FilterUtils.invalidUrl(exchange);
|
||||
}
|
||||
log.debug("2. 获取请求参数: "+ JSON.toJSON(paramMap));
|
||||
//6 获取请求体,修改请求体
|
||||
ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
|
||||
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
|
||||
@@ -90,6 +96,7 @@ public class RequestEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
paramMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
checkSign(sign, dateTimestamp, requestId, paramMap);
|
||||
log.debug("3. 修改请求体:"+encrypt);
|
||||
return Mono.just(encrypt);
|
||||
});
|
||||
|
||||
@@ -101,13 +108,8 @@ public class RequestEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
headers.remove(HttpHeaders.CONTENT_LENGTH);
|
||||
//创建CachedBodyOutputMessage并且把请求param加入,初始化校验信息
|
||||
MyCachedBodyOutputMessage outputMessage = new MyCachedBodyOutputMessage(exchange, headers);
|
||||
|
||||
outputMessage.initial(paramMap, requestId, sign, dateTimestamp);
|
||||
|
||||
//修改响应体
|
||||
MyCachedBodyOutputMessage repOutputMessage = new MyCachedBodyOutputMessage(exchange, headers);
|
||||
repOutputMessage.getBody();
|
||||
|
||||
|
||||
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
|
||||
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
|
||||
@@ -118,7 +120,9 @@ public class RequestEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
//验证签名
|
||||
checkSign(outputMessage.getSign(), outputMessage.getDateTimestamp(), outputMessage.getRequestId(), outputMessage.getParamMap());
|
||||
}
|
||||
log.debug("4. 完成");
|
||||
return outputMessage.getBody();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.demo.gateway.filter;
|
||||
|
||||
import com.demo.gateway.annotations.LoggableGlobalFilter;
|
||||
import com.demo.gateway.utils.AESUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
@@ -11,6 +13,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
@@ -27,11 +30,12 @@ import java.nio.charset.StandardCharsets;
|
||||
* @see ServerHttpResponseDecorator
|
||||
* @since 0.0.1
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Configuration
|
||||
@Component
|
||||
public class ResponseEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
private static final String AES_SECURTY = "MTIzNDU2Nzg5MTIzNDU2Nw=="; //1234567891234567
|
||||
private static final String AES_SECURTY = "MTIzNDU2Nzg5MTIzNDU2Nw==";//1234567891234567
|
||||
private static final Logger log = LogManager.getLogger();
|
||||
/**
|
||||
* 加密 过滤器 优先级
|
||||
* <p>
|
||||
@@ -77,7 +81,8 @@ public class ResponseEncryptionGlobalFilter implements GlobalFilter, Ordered {
|
||||
}
|
||||
|
||||
log.debug("加密后 body:{}", new String(encryption, StandardCharsets.UTF_8));
|
||||
|
||||
HttpHeaders headers = getDelegate().getHeaders();
|
||||
headers.setContentLength(encryption.length);
|
||||
return exchange.getResponse().bufferFactory().wrap(encryption);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.demo.gateway.utils.AESUtil;
|
||||
|
||||
public class test {
|
||||
public static void main(String[] args) {
|
||||
String str = "0uMDI+g2bagWZ6+wlwBGQYjPFu1pJ8oA39/HzrpZT7kX2qT0VPUYlrieNNqEtcWTUWyz3Xn8aIlE8IqyB/AJP+Z4PZunY7NXOdscNam/u8Gmpfzxj8VupNaKw05pXPkNcUGEjVRIUJqmGUEUMJyixuInQkuSqs6InJG9ry4gJE/Iw8AyJwexuD5njeVqAwvwzaocFftGQOzSD0GFzyEyoTNgb0R10wkdt166+qv5XtozWrJ2/BQGk4rkW3zakbqf";
|
||||
String str = "CvCb2zEd9u1VL0zEfulTyppeV0QmnjSwFLjZHEsXdzYdYcXuEo+p3ayKLUwt1mN+";
|
||||
//String encrypt = AESUtil.encrypt(str, "MTIzNDU2Nzg5MTIzNDU2Nw==");
|
||||
String decrypt = AESUtil.decrypt(str, "MTIzNDU2Nzg5MTIzNDU2Nw==");
|
||||
System.out.println(decrypt);
|
||||
|
||||
@@ -21,3 +21,18 @@ spring:
|
||||
redis:
|
||||
port: 6379
|
||||
host: ${REDIS_HOST:localhost}
|
||||
|
||||
|
||||
rootLogger:
|
||||
level: DEBUG
|
||||
appenders:
|
||||
- console
|
||||
|
||||
# 配置控制台输出
|
||||
appenders:
|
||||
- type: console
|
||||
name: CONSOLE
|
||||
target: System.out
|
||||
layout:
|
||||
type: pattern
|
||||
pattern: "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"
|
||||
6
pom.xml
6
pom.xml
@@ -10,9 +10,11 @@
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<modules>
|
||||
<module>gateway</module>
|
||||
<module>common</module>
|
||||
<module>user</module>
|
||||
<module>library</module>
|
||||
|
||||
|
||||
<!-- <module>common</module>-->
|
||||
<!-- <module>user</module>-->
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
Reference in New Issue
Block a user