接口签名校验设计

签名目的

  • 防篡改
  • 防抓包
  • 防刷
  • 更安全

签名的主要防御措施:

一、 验证签名

将有效的参数按字典排序,并 md5 或 sha 加密(可以自定义加密算法)得到 param_sign,服务端依据同样的算法得到 server_sign,对比传递过来的 param_sign,不相等断定签名无效。
如果请求是 RequestBody ,当作 key 为 “body” ,value 为 json 字符串值传入校验。

二、 请求的时间是否在限制的时间内(如:1 分钟内)

判断请求的时间戳是否在允许的范围内

三、 请求方是否被接口服务注册登记

判断 clientId 是否有效

四、 是否重复请求

通过缓存验证 key (由 clientId+nonce 组成)是否已经存在,nonce 是随机生成的字符串
默认开启此功能,并由本地来缓存,可以自定义缓存实现微服务的场景(如 redis 等等)。

WIKI 文档

实现原理

实现机制:通过拦截器,在真正 handler 之前,对请求拦截后统一处理。

我们可以继承 HandlerInterceptorAdapter 类,然后注册给 WebMvcConfigure,这样我们的拦截器就可以生效了

1
2
3
4
5
6
public class SignAutoConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SignInterceptor());
}
}

签名的原理是:

  • 客户端将所有有效参数,将 key 按字典排序,加上密钥,然后 md5 加密得到 sign
  • 服务端用同样的方式得到 sign,比较参数中的 sign 和自己生成的 sign

特性

  • 支持上面提到的所有防御措施
  • 支持多客户端
  • 支持自定义缓存
  • 支持自定义验证器
  • 支持全局和局部的开关控制

客户端工具

Java 客户端工具

SimpleHttpUtil
具体见 1.2 客户端基本使用

Js 客户端工具

参考资料

示例源码

https://github.com/lyloou/component-parent-test/tree/master/component-security-signvalidator-starter-test