关于Kong网关客户端请求的两个小坑

服务端配置了Kong网关,要求请求头携带必须的字段,否则不能通过网关.

添加字段很简单,根据Kong的文档,不校验body的请求头必须字段如下:

-H "Host: hmac.com" \      
-H "Date: Thu, 22 Jun 2017 17:15:21 GMT" \     
-H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line", signature="ujWCGHeec9Xd6UD2zlyxiNMCiXnDOWeVFMu5VeRUxtw="'

Host字段的值替换为你真实的host值.

Date字段有个小坑,一定是格林威治时间,不是东8区的时间!!!!!!!!!!!!!!

附上java代码获取格林威治时间的代码:

DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
String signDate = dateFormat.format(Calendar.getInstance().getTime());

PS:如果你使用东8区的北京时间,你会发现这个时间比你电脑右下角显示的时间要慢8个小时整.这就对了.

Authorization字段直接按照文档上的要求写,username用网关配置的字段.

签名字段计算如下:

signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1"
digest=HMAC-SHA256(, "secret")
base64_digest=base64()

比较好理解,对获取的时间和请求行进行签名.

请求时间用之前的格林威治时间,请求行用抓包工具可以看到,其实就是[请求方式] + [请求地址] + [协议版本]

请求地址不要加host.

注意中间有一个\n,其实是'\n'一个换行符.

如果需要校验body,请求头还需要添加一个字段:

-H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \

字段的值是对body进行计算,方法如下:

body="A small body"
digest=SHA-256(body)
base64_digest=base64(digest)
Digest: SHA-256=

这个字段需要加入签名,最终的请求头如下:

-H "Host: hmac.com" \
-H "Date: Thu, 22 Jun 2017 21:12:36 GMT" \
-H "Digest: SHA-256=SBH7QEtqnYUpEcIhDbmStNd1MxtHg2+feBfWc1105MA=" \
-H 'Authorization: hmac username="alice123", algorithm="hmac-sha256", headers="date request-line digest", signature="gaweQbATuaGmLrUr3HE0DzU1keWGCt3H96M28sSHTG8="' \
-d "A small body"

最终的的签名signature计算的方法如下:

signing_string="date: Thu, 22 Jun 2017 17:15:21 GMT\nGET /requests HTTP/1.1\ndigest: SHA-256=[请求头Disgest字段的值]"
digest=HMAC-SHA256(, "secret")
base64_digest=base64()

注意中间的两个\n和disest字段的加入方式.(官方文档上没有写,自己猜的,测试可以通过).

最终是对类似于这种格式的字符串进行HMAC-SHA256和Base64计算:

date: Fri, 13 Apr 2018 09:12:53 GMT
POST /requests HTTP/1.1
digest: SHA-256=uy7reOKmOLfkc13qRMn5fWCV8Gy9MP0yjbS4sHvlXC0=
END



你可能感兴趣的:(关于Kong网关客户端请求的两个小坑)