背景
在日常开发中,有时候需要开放接口给第三方合作伙伴使用,就像微信、支付宝的开发者平台一样,开放指定功能的接口给到具备开发能力的人员使用;为了保证对应的接口安全性,我们在网关自然是要做拦截校验的,下面我们就来看看在Spring Cloud Zuul中如何实现。
解决方案
1.平台方给到用户生成的appKey和appSecurity,该appKey绑定开放的接口;
2.调用方在请求中携带appKey以及通过相关签名算法计算出来的结果sign;
3.请求经过网关时,需要平台方解开请求校验对应的appKey以及签名结果sign;
4.如果校验通过,那么请求下发给目标服务;否则告知调用方没有调用权限;
相关对接文档如下:
- 准备工作
先在开放平台创建应用程序,并勾选相关功能,最后由开放平台生成appKey和appSecret给到调用方;
- 请求发送
【请求头】 | 必选 | 类型 | 说明 |
---|---|---|---|
app-key | 是 | String | 由开放平台分配的appKey |
app-sign | 是 | String | 请求参数加密后的结果 |
- 计算app-sign
【请求参数加密前需要先进行排序,针对排序后拼接出来的字符串做HmacSHA256加密】
【排序示例】 :
appKey=具体参数值
//排序前请求参数
name=jack
age=11
gender=男
//排序后等待加密字符串:
age=11&gender=男&name=jack&appKey=具体参数值
复制代码
提示:如果Java代码,可使用Collections.sort针对List排序;如果是Map容器,可以使用TreeMap排序。
【加密方式】
private static final String MACSHA256 = "HmacSHA256";
public static String macSha2Base64(String message, String secret) {
byte[] digestBytes = signBySha256(message, secret);
try {
return bytes2Base64(digestBytes, UTF8);
} catch (Exception e) {
return null;
}
}
public static byte[] signBySha256(String message, String secret) {
Mac hmacSha256;
try {
hmacSha256 = Mac.getInstance(MACSHA256);
byte[] keyBytes = secret.getBytes(UTF8);
byte[] messageBytes = message.getBytes(UTF8);
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, MACSHA256));
// 使用HmacSHA256对二进制数据消息Bytes计算摘要
return hmacSha256.doFinal(messageBytes);
} catch (Exception e) {
return null;
}
}
private static String bytes2Base64(byte[] bytes, String charset)
throws UnsupportedEncodingException {
return new String(Base64.getEncoder().encode(bytes), charset);
}
复制代码
示例:
//待加密字符串
age=11&gender=男&name=zouwei&appKey=123456
//测试appSecurity
appSecurity=plokmijnuhb
//加密结果
lHw8EijUbCXnSzAOplMQE2Kwfu8ckTXHy5gITtOtlhw=
复制代码
以上便是调用方的接口对接方案。
开放平台如何实现接口安全性校验
- 创建数据表
-- ----------------------------
-- Table structure for app_security_tbl
-- ----------------------------
DROP TABLE IF EXISTS `app_security_tbl`;
CREATE TABLE `app_security_tbl` (
`id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '用户ID',
`app_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'app key',
`app_secret` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin COMMENT '加密secret',
`create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modified_date` timestamp NULL DEFAULT NULL COMMENT '修改时间',
`merchant_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '商户号',
`remark` varchar(256) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
-- ----------------------------
-- Table structure for app_api_permission_tbl
-- ----------------------------
DROP TABLE IF EXISTS `app_api_permission_tbl`;
CREATE TABLE `app_api_permission_tbl` (
`id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`app_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'app key',
`path` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '接口路径',
`method` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '接口请求方法',
`description` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '接口描述',
`create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modified_date` timestamp NULL DE