一、概述
futu-api-encrypt是一款基于spring-boot和spring-cloud-gateway的接口加解密starter,通spring-boot的简单配置就能够实现各种业务场景下的接口参数校验和加解密。其中包含时间戳 校验、签名校验、对称加密、非对称加密等多种功能,也能够根据白名单、黑名单配置过滤接口地址。同时支持容忍模式,可以灵活处理加密和非加密请求的共存场景。
二、快速开始
基于spring-cloud-gateway(spring-boot类似)
1、引入依赖
<dependency>
<groupId>cn.futuai.open</groupId>
<artifactId>futu-api-encrypt-spring-cloud-gateway-starter</artifactId>
<version>1.3.0</version>
</dependency>
2、配置参数
spring:
cloud:
gateway:
api-encrypt:
# 全局开关
enabled: true
# 加密对称密钥http header key
encrypt-aes-key-header-key: "ek"
# 时间戳http header key
timestamp-header-key: "ts"
# 签名值http header key
sign-header-key: "sign"
# 加密query参数key
encrypt-param-key: "ciphertext"
# rsa非对称加密私钥
rsa-private-key: "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAI6VKvsus/Z0R3zvqre3gzClHJdsCVeKq89hZFFWbg5l3FNbiGZEEiuD1LL+USi5GCxeRK+xEOFTj7I/waRVb3x7V3J1N0q4nNWoZvRey0MTVaBkoHeB5tzn2ZOCBQRJnijXcO58ChcLXOTQId+zDiCBCom/A62gtH8isH4PYoZXAgMBAAECgYBpetrwNa223nDgcWFHRkCMZSmQr8D9fT37Th5rudfzWNG07RssJKGYhY9913xs9vl2IUsI+qH1P98nS9lSXE37mfOKFhfGZIUjAhMb7/w8hhuHpBXopVpUJZW0B46gfPOsrmvq+xiwlI02UYJ1ZOrfdfbvss/Gwtgrk4pMigL1OQJBANRm4mOUMwF+xUxeOLa2Aafke/iwdcxoV1k1gXmTH0B8wf08zDR7heW737YBEvsjyfEpjo7Y0kGSE5zmTWNnuKUCQQCr2XuZeJLqq6etq7IhboPAx8E2xgfOY/hgKPr9IvM8gYee628YhyOynIhOVFGxaf7dMH9eZ1P6jAbvsgm+mFZLAkEAyY0btJyTzg5q0G30aUTKy3OgRDvGfIJiqM+CHkiCdmIsfs5rhD3WsEqYHZBlX5T1cvgZQ+nxkrE4FUHhG7v31QJAYJZ9TNYjJTjTpt5A4V9/OAROCZ4mVw+DU3DVGR/ivJhFBMJpD80s+D/YsMXdoKzlraaLgCDtZ336jBByP6jZnwJBAIGUnbs7eRLcXzlbORdKC/EfkDYS2rrXLFvQhehT7Y8dKHLZfJElnrHB33Qd8R8WP0PsPU6D7EWNU2zVNK1EDxY="
# 容忍模式配置
tolerant-urls:
- /api/public/** # 允许公开接口同时支持加密和非加密访问
- /api/legacy/** # 兼容旧版本接口
log-level:
"default": warn
"[/api/user/code]": info
"[/api/user/code2]": debug
"[/api/user/code3]": warn
"[/api/user/code4]": error
"[/api/user/export]": trace
# 检测模式
check-model:
# 模式
model: black_list
# 黑名单URL列表
black-list:
- /api/user/code
- /api/user/code2
- /api/user/code3
- /api/user/code4
- /api/user/export
timestamp:
# 时间戳校验开关
enabled: true
# 时间戳有效秒数
timestamp-valid-second: 31536000 # 1年
sign:
# 签名校验开关
enabled: true
# 请求解密配置
request-decrypt:
# 是否开启
enabled: true
# 检测模式
check-model:
# 白名单模式
model: white_list
# 白名单URL列表
white-list:
- /api/user/code2
- /api/user/code4
# 响应加密配置
response-encrypt:
# 是否开启
enabled: true
# 检测模式
check-model:
# 黑名单模式
model: black_list
# 黑名单URL列表
black-list:
- /api/user/code
- /api/user/code4
- /api/user/export
3、自定义API异常回调管理器
@Configuration
public class ApiEncryptConfiguration {
public ApiEncryptConfiguration() {
// 网关回调管理器
GatewayApiExceptionCallbackManager.setApiExceptionHandler(new GatewayApiExceptionRequestHandler() {
/**
* 网关API校验失败,就会调用此回调
* @param serverWebExchange serverWebExchange
* @param throwable 异常
* @return mono
*/
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange,
Throwable throwable) {
Response<Void> error = Response.create(ResponseTypeEnum.PARAM_VALID_ERROR);
String errJson = JSONUtil.toJsonStr(error);
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(errJson), String.class);
}
});
}
}
4、容忍模式说明
容忍模式(Tolerant Mode)是一个特殊的功能,允许特定的API接口同时支持加密和非加密的请求。这在以下场景特别有用:
- 接口平滑升级:当需要将现有的非加密接口升级为加密接口时,可以使用容忍模式实现平滑过渡
- 公开接口:某些公开接口可能既需要支持加密访问(如移动端),也需要支持非加密访问(如Web端)
- 向后兼容:为了兼容旧版本的客户端,可以让接口同时支持新旧两种访问方式
使用方式:
- 在配置文件中通过
tolerant-urls
配置需要启用容忍模式的URL列表 - 支持通配符匹配,如
/api/public/**
- 当请求匹配到容忍模式的URL时:
- 如果请求带有加密头(encrypt-aes-key-header-key),则按加密请求处理
- 如果请求没有加密头,则按非加密请求处理
- 无论是否加密,都会执行时间戳和签名校验(如果启用)
三、案例
1、配置网关服务和用户服务
网关服务:
- 引入futu-api-encrypt-spring-cloud-gateway-starter和nacos依赖
- 参考“快速开始”配置API加解密规则
用户服务
- 引入nacos等依赖
- 定义API接口
@Slf4j
@RestController
public class UserController {
@PostMapping("{path}")
public Map<String, Object> code(@PathVariable("path") String path, @RequestParam String test1,
@RequestParam String test2,
@RequestParam String test3,
@RequestBody String body) {
Map<String, Object> map = new HashMap<>();
map.put("path", path);
map.put("test1", test1);
map.put("test2", test2);
map.put("test3", test3);
map.put("body", body);
log.info(String.valueOf(map));
return map;
}
@SneakyThrows
@GetMapping("export")
public void export(HttpServletResponse response) {
HttpHeaders headers = new HttpHeaders();
String name = "测试文件";
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", UriUtils.encode(name, StandardCharsets.UTF_8) + ".xlsx");
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
response.setHeader(entry.getKey(), String.join(";", entry.getValue()));
}
IOUtils.copy(new FileInputStream("D:\project\personal\futu-api-encrypt\example\doc\测试.xlsx"),
response.getOutputStream());
}
}
2、发起请求
请求参数加密,响应结果中文
一、概述
futu-api-encrypt是一款基于spring-boot和spring-cloud-gateway的接口加解密starter,通spring-boot的简单配置就能够实现各种业务场景下的接口参数校验和加解密。其中包含时间戳 校验、签名校验、对称加密、非对称加密等多种功能,也能够根据白名单、黑名单配置过滤接口地址。同时支持容忍模式,可以灵活处理加密和非加密请求的共存场景。
二、快速开始
基于spring-cloud-gateway(spring-boot类似)
1、引入依赖
<dependency>
<groupId>cn.futuai.open</groupId>
<artifactId>futu-api-encrypt-spring-cloud-gateway-starter</artifactId>
<version>1.3.0</version>
</dependency>
2、配置参数
spring:
cloud:
gateway:
api-encrypt:
# 全局开关
enabled: true
# 加密对称密钥http header key
encrypt-aes-key-header-key: "ek"
# 时间戳http header key
timestamp-header-key: "ts"
# 签名值http header key
sign-header-key: "sign"
# 加密query参数key
encrypt-param-key: "ciphertext"
# rsa非对称加密私钥
rsa-private-key: "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAI6VKvsus/Z0R3zvqre3gzClHJdsCVeKq89hZFFWbg5l3FNbiGZEEiuD1LL+USi5GCxeRK+xEOFTj7I/waRVb3x7V3J1N0q4nNWoZvRey0MTVaBkoHeB5tzn2ZOCBQRJnijXcO58ChcLXOTQId+zDiCBCom/A62gtH8isH4PYoZXAgMBAAECgYBpetrwNa223nDgcWFHRkCMZSmQr8D9fT37Th5rudfzWNG07RssJKGYhY9913xs9vl2IUsI+qH1P98nS9lSXE37mfOKFhfGZIUjAhMb7/w8hhuHpBXopVpUJZW0B46gfPOsrmvq+xiwlI02UYJ1ZOrfdfbvss/Gwtgrk4pMigL1OQJBANRm4mOUMwF+xUxeOLa2Aafke/iwdcxoV1k1gXmTH0B8wf08zDR7heW737YBEvsjyfEpjo7Y0kGSE5zmTWNnuKUCQQCr2XuZeJLqq6etq7IhboPAx8E2xgfOY/hgKPr9IvM8gYee628YhyOynIhOVFGxaf7dMH9eZ1P6jAbvsgm+mFZLAkEAyY0btJyTzg5q0G30aUTKy3OgRDvGfIJiqM+CHkiCdmIsfs5rhD3WsEqYHZBlX5T1cvgZQ+nxkrE4FUHhG7v31QJAYJZ9TNYjJTjTpt5A4V9/OAROCZ4mVw+DU3DVGR/ivJhFBMJpD80s+D/YsMXdoKzlraaLgCDtZ336jBByP6jZnwJBAIGUnbs7eRLcXzlbORdKC/EfkDYS2rrXLFvQhehT7Y8dKHLZfJElnrHB33Qd8R8WP0PsPU6D7EWNU2zVNK1EDxY="
# 容忍模式配置
tolerant-urls:
- /api/public/** # 允许公开接口同时支持加密和非加密访问
- /api/legacy/** # 兼容旧版本接口
log-level:
"default": warn
"[/api/user/code]": info
"[/api/user/code2]": debug
"[/api/user/code3]": warn
"[/api/user/code4]": error
"[/api/user/export]": trace
# 检测模式
check-model:
# 模式
model: black_list
# 黑名单URL列表
black-list:
- /api/user/code
- /api/user/code2
- /api/user/code3
- /api/user/code4
- /api/user/export
timestamp:
# 时间戳校验开关
enabled: true
# 时间戳有效秒数
timestamp-valid-second: 31536000 # 1年
sign:
# 签名校验开关
enabled: true
# 请求解密配置
request-decrypt:
# 是否开启
enabled: true
# 检测模式
check-model:
# 白名单模式
model: white_list
# 白名单URL列表
white-list:
- /api/user/code2
- /api/user/code4
# 响应加密配置
response-encrypt:
# 是否开启
enabled: true
# 检测模式
check-model:
# 黑名单模式
model: black_list
# 黑名单URL列表
black-list:
- /api/user/code
- /api/user/code4
- /api/user/export
3、自定义API异常回调管理器
@Configuration
public class ApiEncryptConfiguration {
public ApiEncryptConfiguration() {
// 网关回调管理器
GatewayApiExceptionCallbackManager.setApiExceptionHandler(new GatewayApiExceptionRequestHandler() {
/**
* 网关API校验失败,就会调用此回调
* @param serverWebExchange serverWebExchange
* @param throwable 异常
* @return mono
*/
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange,
Throwable throwable) {
Response<Void> error = Response.create(ResponseTypeEnum.PARAM_VALID_ERROR);
String errJson = JSONUtil.toJsonStr(error);
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(errJson), String.class);
}
});
}
}
4、容忍模式说明
容忍模式(Tolerant Mode)是一个特殊的功能,允许特定的API接口同时支持加密和非加密的请求。这在以下场景特别有用:
- 接口平滑升级:当需要将现有的非加密接口升级为加密接口时,可以使用容忍模式实现平滑过渡
- 公开接口:某些公开接口可能既需要支持加密访问(如移动端),也需要支持非加密访问(如Web端)
- 向后兼容:为了兼容旧版本的客户端,可以让接口同时支持新旧两种访问方式
使用方式:
- 在配置文件中通过
tolerant-urls
配置需要启用容忍模式的URL列表 - 支持通配符匹配,如
/api/public/**
- 当请求匹配到容忍模式的URL时:
- 如果请求带有加密头(encrypt-aes-key-header-key),则按加密请求处理
- 如果请求没有加密头,则按非加密请求处理
- 无论是否加密,都会执行时间戳和签名校验(如果启用)
三、案例
1、配置网关服务和用户服务
网关服务:
- 引入futu-api-encrypt-spring-cloud-gateway-starter和nacos依赖
- 参考“快速开始”配置API加解密规则
用户服务
- 引入nacos等依赖
- 定义API接口
@Slf4j
@RestController
public class UserController {
@PostMapping("{path}")
public Map<String, Object> code(@PathVariable("path") String path, @RequestParam String test1,
@RequestParam String test2,
@RequestParam String test3,
@RequestBody String body) {
Map<String, Object> map = new HashMap<>();
map.put("path", path);
map.put("test1", test1);
map.put("test2", test2);
map.put("test3", test3);
map.put("body", body);
log.info(String.valueOf(map));
return map;
}
@SneakyThrows
@GetMapping("export")
public void export(HttpServletResponse response) {
HttpHeaders headers = new HttpHeaders();
String name = "测试文件";
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", UriUtils.encode(name, StandardCharsets.UTF_8) + ".xlsx");
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
response.setHeader(entry.getKey(), String.join(";", entry.getValue()));
}
IOUtils.copy(new FileInputStream("D:\\project\\personal\\futu-api-encrypt\\example\\doc\\测试.xlsx"),
response.getOutputStream());
}
}