OpenSearch服务会对每个访问的请求进行身份验证,通过使用Access Key ID和Access Key Secret进行对称加密的方法来验证请求的发送者身份。Access Key ID和Access Key Secret由阿里云官方颁发给访问者(可以通过阿里云官方网站申请和管理),其中Access Key ID用于标识访问者的身份。
Access Key Secret是用于加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密,只有阿里云和用户知道。
需在 HTTP 请求 Header 头信息中,添加 Authorization(授权)来包含签名(Signature)信息,表明该请求已被授权。请求Header 中也需要包含文档下面“签名示例”部分中“请求Header”中提到的这些相关的请求Header。
请求 Header 中包含的参数都必须要参与签名(例如 Content-Md5,Content-Type,Date,Http专有 Header 等等)。
"Authorization: OPENSEARCH " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
VERB + "\n"
+ Content-Md5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedOpenSearchHeaders
+ CanonicalizedResource))
参数 | 描述 |
---|---|
AccessKeyId | 不能为空,请求Header 中的 Authorization 需要用到该 AccessKeyId 值,表示访问指定应用的用户 |
AccessKeySecret | 不能为空,签名所需的秘钥 |
VERB | 不能为空,表示请求操作方法。HTTP 请求 Method,主要有 PUT、GET、POST、HEAD、DELETE 等,不同接口Method也不同 |
\n | 换行符 |
Content-MD5 | 请求body有内容时,不能为空。该参数值为,请求body 的MD5值。该请求头用于消息合法性的检查(消息内容是否与发送时一致),例如 4991ef0788236a8f280fed0db928e74e ,对于不发送 body 的请求,例如查询请求,此值请留空。详情参看 RFC2616 Content-MD5 |
Content-Type | application/json |
Date | 不能为空,表示此次操作时间,且必须为 秒级 的 ISO 格式,如“2017-08-09T01:54:12Z”,时间为UTC时间;如果此时间和 OpenSearch 服务器的时间差正负 15 分钟以上,服务器将拒绝该服务,并返回 HTTP 403 错误 |
CanonicalizedOpenSearchHeaders | 不能为空,用于区分每次请求,以 X-Opensearch- 为前缀的Http专有 Header组合,例如 X-Opensearch-Nonce ,在签名过程中这些Http专有 Header名必须全部小写,例如 x-opensearch-nonce ,若这些Http专有Header是作为请求Header参数,则需按照原格式名显示若请求 Header 中不包含这些Http专有 Header,该参数不参与签名计算,在签名方法中直接去掉该参数。 |
CanonicalizedResource | 不能为空,表示用户此次请求路径,例如/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did |
请求签名参数 | 必须 | 请求 Header 参数 | 必须 |
---|---|---|---|
AccessKeySecret | 是 | Date | 是 |
VERB | 是 | X-Opensearch-Nonce | 是 |
Date | 是 | Authorization | 是 |
x-opensearch-nonce | 是 | ||
canonicalized_resource | 是 |
请求签名参数 | 必须 | 请求 Header 参数 | 必须 |
---|---|---|---|
AccessKeySecret | 是 | Content-MD5 | 是 |
VERB | 是 | Date | 是 |
Content-MD5 | 是 | Authorization | 是 |
Date | 是 | ||
canonicalized_resource | 是 |
所有以 X-Opensearch-
为前缀的 Http专有 Header 被称为 CanonicalizedOpenSearchHeaders,其他非 Http专有 Header 将不被纳入验证
将所有以 X-Opensearch-
为前缀的Http专有 Header 对应的内容补齐,例如X-Opensearch-Nonce : 150224365226248
(该Nonce参数值,可由10位时间戳+5位随机值(10000~99999)组合而成,例如150224365226248
),再去除所有值为空的Http专有 Header
将这些有对应内容值的Http专有 Header 按照名称的字典序进行升序排序
再将这些排序后的专有 Header名,全部转换成小写字母,例如将 X-Opensearch-Nonce : 150224365226248
转换成 x-opensearch-nonce : 150224365226248
删除请求头和内容之间分隔符两端出现的任何空格。例如该 x-opensearch-nonce : 150224365226248
参数,删除两端空格后为:x-opensearch-nonce:150224365226248
最后将每个请求头及对应内容作为一个单位项,再将每一项之间用 \n
连接拼成最后的 CanonicalizedOpenSearchHeaders,注意最后一个也要有 \n
注意:
- 若查询请求Header中不包含此处Http专有 Header,即该参数中一个Http专有 Header都没有,则无需
\n
,只需在签名方法中去掉该CanonicalizedOpenSearchHeaders签名参数即可,该参数不参与签名计算。- 将Http专有 Header添加到Header中时,不能是转换后的小写形式,需按原格式显示
对 path 进行urlencode后,再替换 %2F
为 /
,下面的app_schema_demo需替换为自己应用名,常见 path 如下所示
/v3/openapi/apps/app_schema_demo/search
/v3/openapi/apps/app_schema_demo/suggest/suggest/search
/v3/openapi/apps/appid
/v3/openapi/apps/app_schema_demo/tab/actions/bulk
query 部分由查询参数构成,参数为键值对形式
参数名
后比较参数值
的顺序,按照字典升序参数名
和参数值
进行 urlencode,再将参数名和对应参数值之间通过=
拼接&
分割拼接并存储到 query 字符串中+
字符,替换成 %20
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did
注意:
- query参数中各个查询子句之间必须要用
&&
进行拼接- 若为推送操作,则只需将 path 部分拼接至 CanonicalizedResource 字符串中即可
构建方法参考开头部分描述,需添加到请求 Header 中
LTAIvDPtKBhpSPki
,Signature为 EG+VyxqNhSsPgdaFYfl5Wd7Pulo=
,python3示例代码如下
headers['Authorization'] = 'OPENSEARCH ' + 'LTAIvDPtKBhpSPki' + ':' + 'EG+VyxqNhSsPgdaFYfl5Wd7Pulo='.decode('utf-8')
假如参数值如下
OPENSEARCH LTAIvDPtKBhpSPki:EG+VyxqNhSsPgdaFYfl5Wd7Pulo=
5OCGljiVeXLvO49QaEYuYQjUb1HAZQ
GET
application/json
2017-08-09T01:54:12Z
x-opensearch-nonce:150224365226248
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did
请求Header | 签名字符串计算公式 | 签名字符串 |
---|---|---|
‘Content-MD5’: ‘’, ‘Content-Type’: ‘application/json’, ‘Authorization’: ‘OPENSEARCH LTAIvDPtKBhpSPki:EG+VyxqNhSsPgdaFYfl5Wd7Pulo=’, ‘X-Opensearch-Nonce’: ‘150224365226248’, ‘Date’: ‘2017-08-09T01:54:12Z’ |
Signature = base64(hmac-sha1( AccessKeySecret, VERB + “\n” + Content-Md5 + “\n” + Content-Type + “\n” + Date + “\n” + CanonicalizedOpenSearchHeaders + CanonicalizedResource)) |
5OCGljiVeXLvO49QaEYuYQjUb1HAZQ , GET\n \n application/json\n 2017-08-09T01:54:12Z\n x-opensearch-nonce:150224365226248\n /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did |
注意:
- 请求Header中参数值需与签名方法中对应参数值保持一致
python3 示例代码:
import hmac
import base64
signature_string = '\n'.join(['GET',
'',
'application/json',
'2017-08-09T01:54:12Z',
'x-opensearch-nonce:150224365226248',
'/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did'])
signature_hmac = hmac.new('5OCGljiVeXLvO49QaEYuYQjUb1HAZQ'.encode('utf-8'), signature_string.encode('utf-8'), 'sha1')
signature = base64.b64encode(signature_hmac.digest())
假如AccessKeySecret值为 5OCGljiVeXLvO49QaEYuYQjUb1HAZQ
那么通过上面的签名方法构造出来的签名值为 EG+VyxqNhSsPgdaFYfl5Wd7Pulo=
请求串 = host + CanonicalizedResource
需在 HTTP 请求 Header 头信息中增加 Authorization(授权)来包含签名(Signature)信息,表明该请求已被授权,同时Header中也需要包含上面提到的这些相关的请求Header。(host为应用访问API地址)
最终search查询请求串
http://host/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did
最终suggest查询请求串 http://host/v3/openapi/apps/app_schema_demo/suggest/suggest/search?query=%E6%A0%87%E9%A2%98&hits=10
最终查询指定应用信息查询请求串,下面最后一部分为“appid”值,假设为120001234该值,替换后如下所示,该查询请求也需包含Authorization授权签名参数(无需指定查询参数) http://host/v3/openapi/apps/120001234
最终推送数据请求串,此处推送数据需放在body体中 http://host/v3/openapi/apps/app_schema_demo/tab/actions/bulk
目前已对外公开 v3版官方Java SDK 和 PHP SDK,且PHP SDK已包含v3api签名过程实现源码,直接调用这些方法即可使用,也可参考 PHP SDK 签名实现过程源码,或参考本文档v3api签名过程来实现其它语言SDK。
因目前OpenSearch官方,没有正式对外提供官方的 python版 和 C#版 SDK,为方便用户参考实现该文档描述签名过程,此处提供 python 版查询签名Demo,以及C# 版查询和推送签名Demo,以供用户参考实现本文档签名操作
【特别注意】
在文档使用中是否遇到以下问题
更多建议
匿名提交