个人资料
认证功能的位置位于基础服务的接入网关中。
1 .认证概要
该验证方案在api级别进行,并使用访问密钥/安全密钥加密方法验证请求调用方的身份。
访问网关接收到来自服务调用方的要求后,使用与相同的SK相同的认证机构生成认证字符串,与用户要求中包含的认证字符串进行对照。 如果验证字符串相同,则认为用户具有指定的操作权限,并执行相关操作。 如果验证字符串不同,操作将被忽略并返回错误代码。
2 .认证过程
业务云方面的请求
note left of业务云端:预分配的AK/SK
业务云侧-业务云侧:生成认证字符串
业务云端-网关:携带认证字符串的业务请求
网关-网关:认证
网关---业务云端:认证失败,返回401
网关-基础服务:认证成功,透明地传达请求
来自业务方面的要求
业务侧-业务云侧:获取携带有认证字符串api的请求url
note right of业务云端:预置分配的AK/SK
业务云侧-业务云侧:生成认证字符串
业务云侧-业务侧:返回携带认证字符串url
商务端-网关:使用从商业云端返回的url进行业务请求
网关-网关:认证
网关---业务云端:认证失败,返回401
网关-基础服务:认证成功,透明地传达请求
3 .认证字符串生成概要
3.1概述
在生成验证字符串之前,必须首先生成Signature。 要生成Signature,必须首先构建CanonicalRequest并计算SigningKey。
注:
函数名称
功能说明
HMAC-SHA256-HEX (
调用HMAC SHA256算法,基于开发者提供的密钥(key )和密文)输出密码摘要,并将结果转换为小写格式的十六进制字符串。
Lowercase () )
将字符串全部小写。
Trim () ) )。
删除字符串的开头和末尾的空白字符。
UriEncode () )
根据RFC 3986," URI非保留字符"包括字母(A-Z、A-Z )、数字(0-9)、连字符()-)、点()、下划线(_ )、波浪线()
1 .将字符串转换为UTF-8编码的字节流
2 .保留所有“URI非保留字符”
3 .对于剩下的字节,编写一次RFC 3986中规定的百分号代码(Percent-encoding )。 也就是说,一个“%”后跟两个表示该字节值的十六进制字符,并且所有字符都以大写字母表示。
UriEncodeExceptSlash (
UriEncode (与类似,但有一个区别:斜线/)不进行编码。 一个简单的实现方法是调用UriEncode (),并将结果中的所有/替换为/
3.2生成canonical request
canonical request=http method 'n ' canonical uri 'n ' canonical query string 'n ' canonical headers
http方法:全部大写。 支持5种:
获取
信箱
输出
DELETE
头儿
canonical uri :对URL中的绝对路径进行编码的结果。 绝对路径必须以“/”开头,不能以“/”开头。 空路径为“/”。 即canonical uri=uriencodeexceptslash (path )。
示例:
如果URL是https://Bos.cn-n1.Baidu BCE.com/example /测试,则该URL Path是/example/测试,并将其归一化为CanonicalURI=/example/测试
canonicalquerystring:URL中的querystring(querystring即URL中的“? ”后的“key1=valve1 key2=valve2”字符串)进行编码的结果。
编码方法如下。
以Query String为根据分解为几个项目,分别是key=value或者只是key的形式。
对分解后的各项目进行以下处理。
key是授权的,直接忽略。
对于只有key的项目,变换为uriencode(key ) '='的形式。
关于key=value的项目,变换为uriencode(key ) '
=" + UriEncode(value) 的形式。这里value可以是空字符串。将上面转换后的所有字符串按照字典顺序排序。
将排序后的字符串按顺序用 & 符号链接起来。
举例:
若URL为https://bos.cn-n1.baidubce.com/example?text&text1=测试&text10=test,在这个例子中Query String是 text&text1=测试&text10=test。
根据 & 拆开成 text 、text1=测试 和 text10=test 三项。
对每一项进行处理:
text => UriEncode("text") + "=" => text=
text1=测试 => UriEncode("text1") + "=" + UriEncode("测试") => text1=%E6%B5%8B%E8%AF%95
text10=test => UriEncode("text10") + "=" + UriEncode("test")=> text10=test
对 text= 、 text1=%E6%B5%8B%E8%AF%95 和 text10=test 按照字典序进行排序。它们有共同前缀text,但是=的ASCII码比所有数字的ASCII码都要大,因此 text1=%E6%B5%8B%E8%AF%95 和 text10=test 排在 text= 的前面。同样,text10=test 要排在 text1=%E6%B5%8B%E8%AF%95 之前。最终结果是 text10=test 、text1=%E6%B5%8B%E8%AF%95 、text= 。
把排序好的三项 text10=test 、 text1=%E6%B5%8B%E8%AF%95 、 text= 用&连接起来得到 text10=test&text1=%E6%B5%8B%E8%AF%95&text=。
CanonicalHeaders:对HTTP请求中的Header部分进行选择性编码的结果。
您可以自行决定哪些Header 需要编码。唯一要求是Host域必须被编码。大多数情况下,我们推荐您对以下Header进行编码,也可以使用其他header,此处不做限制:
Host
Content-Length
Content-Type
Content-MD5
对于每个要编码的Header进行如下处理:
将Header的名字变成全小写。
将Header的值去掉开头和结尾的空白字符。
经过上一步之后值为空字符串的Header忽略,其余的转换为 UriEncode(name) + ":" + UriEncode(value) 的形式。
把上面转换后的所有字符串按照字典序进行排序。
将排序后的字符串按顺序用n符号连接起来得到最终的CanonicalQueryHeaders。
举例:
不使用signedHeaders默认值。若希望对 Date 进行编码,则需要用到signedHeaders。
要编码的Header如下:
Host: bj.bcebos.com
Date: Mon, 27 Apr 2015 16:23:49 +0800
Content-Type: text/plain
Content-Length: 8
Content-Md5: NFzcPqhviddjRNnSOGo4rw==
首先把所有名字都改为小写。
host: bj.bcebos.com
date: Mon, 27 Apr 2015 16:23:49 +0800
content-type: text/plain
content-length: 8
content-md5: NFzcPqhviddjRNnSOGo4rw==
将Header的值去掉开头和结尾的空白字符。
host:bj.bcebos.com
date:Mon, 27 Apr 2015 16:23:49 +0800
content-type:text/plain
content-length:8
content-md5:NFzcPqhviddjRNnSOGo4rw==
做UriEncode。
host:bj.bcebos.com
date:Mon%2C%2027%20Apr%202015%2016%3A23%3A49%20%2B0800
content-type:text%2Fplain
content-length:8
content-md5:NFzcPqhviddjRNnSOGo4rw%3D%3D?
把上面转换后的所有字符串按照字典序进行排序。
content-length:8
content-md5:NFzcPqhviddjRNnSOGo4rw%3D%3D?
content-type:text%2Fplain
date:Mon%2C%2027%20Apr%202015%2016%3A23%3A49%20%2B0800
host:bj.bcebos.com
将排序后的字符串按顺序用n符号连接起来得到最终结果。
content-length:8
content-md5:NFzcPqhviddjRNnSOGo4rw%3D%3D?
content-type:text%2Fplain
date:Mon%2C%2027%20Apr%202015%2016%3A23%3A49%20%2B0800
host:bj.bcebos.com
这时候认证字符串的signedHeaders内容应该是
content-length;content-md5;content-type;date;host
3.3 生成SigningKey
SigningKey = HMAC-SHA256-HEX(sk, authStringPrefix),其中:
sk为用户的Secret Access Key,可以通过在控制台中进行查询,关于SK的获取方法,请参看获取AK/SK。
authStringPrefix代表认证字符串的前缀部分,即:auth-v1/{accessKeyId}/{timestamp}/{expirationPeriodInSeconds}。
3.4 生成Signature
Signature = HMAC-SHA256-HEX(SigningKey, CanonicalRequest)
3.5 生成认证字符串
认证字符串 = auth-v1/{accessKeyId}/{timestamp}/{expirationPeriodInSeconds}/{signedHeaders}/{signature}
timestamp:签名生效UTC时间,格式为yyyy-mm-ddThh:mm:ssZ,例如:2015-04-27T08:23:49Z,默认值为当前时间。(为实现方便,直接使用时间戳!!)
expirationPeriodInSeconds:签名有效期限,从timestamp所指定的时间开始计算,时间为秒,默认值为1800秒(30)分钟。
signedHeaders:签名算法中涉及到的HTTP头域列表。HTTP头域名字一律要求小写且头域名字之间用分号(;)分隔,如host;range;x-bce-date。列表按照字典序排列。当signedHeaders为空时表示取默认值。
标签:UriEncode,aksk,认证,content,云侧,text,字符串,鉴权
来源: https://www.cnblogs.com/xxxuwentao/p/10344964.html