Apache ShenYu 网关签名实战:AK/SK鉴权技术详解

Apache ShenYu 网关签名实战:AK/SK鉴权技术详解

此文档编写时使用的版本为 Apache ShenYu 2.6.0

Sign插件,用来对请求进行签名认证,支持请求头进行鉴权和请求体进行鉴权。

  • 采用 AK/SK 鉴权技术方案。
  • 采用鉴权插件,责任链的模式来完成。
  • 当鉴权插件开启,并配置所有接口鉴权时候生效。
一 插件的鉴权配置

sign插件的 1.0.0 版本

  • 第一步:AK/SK由网关来进行分配,比如分配给你的AK为: CBB993DD88CF4A119F6FD771C963976B SK为:FE9C196A16C44F649F07A9F640AA7691
  • 第二步:确定好你要访问的网关路径 比如 /pub/captcha
  • 第三步:构造参数(以下是通用参数)
字段描述
timestamp当前时间戳(String类型)当前时间的毫秒数(网关会过滤掉10分钟之前的请求)
path/pub/captcha就是你需要访问的接口路径(根据你访问网关接口自己变更)
version1.0.0当前鉴权算法为1.0.0

对上述3个字段进行 key 的自然排序,然后进行字段与字段值拼接最后再拼接上 SK ,代码示例。

1)无请求体的签名参数验证

第一步:首先构造一个 Map

//timestamp为毫秒数的字符串形式 String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli())   
Map<String, String> map = Maps.newHashMapWithExpectedSize(3);
map.put("timestamp", "1725500864289");  //值应该为毫秒数的字符串形式
map.put("path", "/pub/captcha");
map.put("version", "1.0.0");

第二步:进行 Key 的自然排序,然后 KeyValue值拼接最后再拼接分配给你的 SK

List<String> storedKeys = Arrays.stream(map.keySet()
                .toArray(new String[]{}))
        .sorted(Comparator.naturalOrder())
        .collect(Collectors.toList());

final String sign = storedKeys.stream()
        .map(key -> String.join("", key, map.get(key)))
        .collect(Collectors.joining()).trim()
        .concat("FE9C196A16C44F649F07A9F640AA7691");

你得到的 sign 值应该为:

 path/pub/captchatimestamp1725500864289version1.0.0FE9C196A16C44F649F07A9F640AA7691

第三步:进行 MD5 加密后转成大写。

DigestUtils.md5DigestAsHex(sign.getBytes()).toUpperCase()

最后得到的值为:

5D8C6E2E06E9AF128647EC6C3D27F31C
2) 有请求体,请求头的签名参数验证

第一步: 首先构造一个 Map 。并且该map必须存储请求体的每个节点信息

        Map<String, String> map = Maps.newHashMapWithExpectedSize(3);
        //timestamp is string format of millisecond. String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli())
        map.put("timestamp", "1725500864289");  // Value should be string format of milliseconds
        map.put("path", "/sys/lgn");
        map.put("version", "1.0.0");
        // if your request body is:{"mobile":"13688889999","password":"awlxninsnregxljprx8yvhzilm0tnhda","key":"53a55746-ee0f-4b5c-8750-1a9694d8c730","captcha":"qMvN"}
        map.put("mobile", "13688889999");
        map.put("password", "awlxninsnregxljprx8yvhzilm0tnhda");
        map.put("key", "53a55746-ee0f-4b5c-8750-1a9694d8c730");
        map.put("captcha", "qMvN");

第二步:进行 Key 的自然排序,然后 KeyValue值拼接最后再拼接分配给你的 SK

   List<String> storedKeys = Arrays.stream(map.keySet()
                        .toArray(new String[]{}))
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
   final String sign = storedKeys.stream()
                .map(key -> String.join("", key, map.get(key)))
                .collect(Collectors.joining()).trim()
                .concat("FE9C196A16C44F649F07A9F640AA7691");
  • 你得到的 sign 值应该为:captchaqMvNkey53a55746-ee0f-4b5c-8750-1a9694d8c730mobile13688889999passwordawlxninsnregxljprx8yvhzilm0tnhdapath/sys/lgntimestamp1725500864289version1.0.0FE9C196A16C44F649F07A9F640AA7691

第三步:进行 MD5 加密后转成大写。

DigestUtils.md5DigestAsHex(sign.getBytes()).toUpperCase()
  • 最后得到的值为: 6D8BCA2A50F33A8F98A3E8E8D958BBB9.
二 示例请求网关
  • 假如你访问的路径为:/pub/captcha

  • 访问地址 :

    http://你的域名/pub/captcha。
    
  • 设置header头,header头参数为:

字段描述
timestamp1725500864289上述你进行签名的时候使用的时间值
appKeyCBB993DD88CF4A119F6FD771C963976B分配给你的AK值
sign5D8C6E2E06E9AF128647EC6C3D27F31C上述得到的签名值
version1.0.0写死,就为这个值
  • 签名插件会默认过滤 10 分钟之前的请求(默认值参考官方文档,这里有做修改)
  • 如果认证不通过会返回 code401message 可能会有变动。
{  "code": 401,  "message": "sign is not pass,Please check you sign algorithm!",  "data": null}

详情参考:Apache ShenYu 的 SignPlugin 插件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值