python实现组合cmn公式_python %x

关于

python %x的搜索结果

问题

scalene 一个 Python 的高性能 CPU 和内存分析器

Scalene 是一个 Python 的高性能 CPU 和 内存分析器,它可以做到很多其他Python分析器不能做到的事情。它在能提供更多详细信息的同时,比其他的分析器要快几个数量级。

Scalene 是 很快...

huc_逆天

2020-05-21 17:13:10

17 浏览量

回答数 1

问题

tornado 模板中如何使用datetime.datime.strptime函数?报错

大家好,今天遇到一个问题!

就是在tornado模板中需要转换日期字符串的格式!

例如,收到的字符串是'2015-10-11',我需要转换成&...

爱吃鱼的程序员

2020-06-12 10:47:39

0 浏览量

回答数 1

回答

在同一个文件夹下

调用函数:

A.py文件:

[python] view plain copydef add(x,y):

print('和为:%d'%(x+y))

B.py文件:[python] view plain copyimport A A.add(1,2)

或[python] view plain copyfrom A import add add(1,2)

调用类:

A.py文件:

[python] view plain copyclass A:

def __init__(self,xx,yy):

self.x=xx

self.y=yy

def add(self):

print("x和y的和为:%d"%(self.x+self.y))

B.py文件:[python] view plain copyfrom A import A a=A(2,3) a.add()

或[python] view plain copyimport A a=A.A(2,3) a.add()

在不同文件夹下

A.py文件的文件路径:E:PythonProjectwinycg

B.py文件:[python] view plain copyimport sys sys.path.append(r'E:PythonProjectwinycg') '''''python import模块时, 是在sys.path里按顺序查找的。 sys.path是一个列表,里面以字符串的形式存储了许多路径。 使用A.py文件中的函数需要先将他的文件路径放到sys.path中''' import A

a=A.A(2,3) a.add()

xuning715

2019-12-02 01:10:15

0 浏览量

回答数 0

回答

#!/usr/bin/python

# -*- coding: UTF-8 -*-

def exchange(a,b):

a,b = b,a

return (a,b)

if __name__ == '__main__':

x = 10

y = 20

print 'x = %d,y = %d' % (x,y)

x,y = exchange(x,y)

print 'x = %d,y = %d' % (x,y)

以上实例输出结果为:

x = 10,y = 20

x = 20,y = 10

珍宝珠

2019-12-02 03:18:04

0 浏览量

回答数 0

问题

使用Selenium 在 div中 查找 class

我试图通过python中的Selenium访问并单击“ X”按钮,以便能够重定向到下一页并从中加载一些信息。但是,我很难找到元素,不知道这是由于在类内还是其他原因。你们能帮我实际点击一下按钮吗...

is大龙

2020-03-24 22:46:17

3 浏览量

回答数 1

问题

初学python,求助? 400 报错

初学python,求助? 400 报错

判断润年的小程序

elif year % 4 == 0 and year %100 != 0 or year % 400 == 0

这句话在2....

爱吃鱼的程序员

2020-05-31 00:38:27

0 浏览量

回答数 1

问题

RedisLive监控实时数据报错?报错

@China_OS 你好,想跟你请教个问题:

先说下系统环境:

CentOS release 6.6 (Final)

Python 2.6.6(Python 2.7.10 之前以为是py...

爱吃鱼的程序员

2020-06-12 15:28:27

0 浏览量

回答数 1

问题

Str 切片后操作的 Runtime 比切片后重新赋值的 Runtime 慢的多,为什么?

我测试了两个代码:

代码 1:

def check1(x):

y = str(x)[::-1]

return str(x)== y

运行结果:

...

几许相思几点泪

2019-12-29 18:43:08

3 浏览量

回答数 1

问题

如何将matlab代码转换成python代码?(

我刚接触python,并尝试在python 3中转换这个优化的matlab代码,但在python中的结果是完全不同的。有人可以重新检查代码并提供适当的解决方案。matlab代码显示优化值为10^-24,pytho...

kun坤

2019-12-25 21:47:26

3 浏览量

回答数 0

问题

Python中[w*7*24 for w in range(10)]和['wee?报错

在《机器学习系统设计》一书中,第一章1.5节有一行代码: plt.xticks([w724 for w in range(10)],['week %i'%w in range(10)]) 这里的&...

爱吃鱼的程序员

2020-06-14 16:11:22

0 浏览量

回答数 1

问题

不好的请求使用flask

我正在开发一个类似于facebook的应用程序。 我正在尝试渲染一个朋友的资料。 当我点击应该呈现配置文件页面的链接时,我得到一个糟糕的请求错误 我用烧瓶,python, html和JS 下面是服务器端的pyth...

kun坤

2019-12-28 14:29:24

0 浏览量

回答数 1

问题

在python 3中使用win32api / com模块时,有没有办法解决unicode问题?

我正在浏览收件箱中的电子邮件并检查特定的单词集。它适用于大多数电子邮件,但其中一些不解析。我查看了破碎的电子邮件。

print (msg.Body.encode('utf8'))我的问题消息都以b'开头。像这样

b'xe6xa0xbcxe6...

一码平川MACHEL

2019-12-01 19:31:56

767 浏览量

回答数 1

回答

#!/usr/bin/python

# -*- coding: UTF-8 -*-

MAXIMUM = lambda x,y : (x > y) * x + (x < y) * y

MINIMUM = lambda x,y : (x > y) * y + (x < y) * x

if __name__ == '__main__':

a = 10

b = 20

print 'The largar one is %d' % MAXIMUM(a,b)

print 'The lower one is %d' % MINIMUM(a,b)

以上实例输出结果为:

The largar one is 20

The lower one is 10

珍宝珠

2019-12-02 03:18:04

0 浏览量

回答数 0

问题

初学python,求助?报错

判断润年的小程序

elif year % 4 == 0 and year %100 != 0 or year % 400 == 0

这句话在2.x中能执行,但是在3.x中报错

Typ...

爱吃鱼的程序员

2020-06-22 15:07:56

0 浏览量

回答数 1

回答

#!/usr/bin/python

# -*- coding: UTF-8 -*-

a = int(raw_input("请输入一个数字:\n"))

x = str(a)

flag = True

for i in range(len(x)/2):

if x[i] != x[-i - 1]:

flag = False

break

if flag:

print "%d 是一个回文数!" % a

else:

print "%d 不是一个回文数!" % a

以上实例输出结果为:

请输入一个数字:

12321

12321 是一个回文数!

珍宝珠

2019-12-02 03:18:00

0 浏览量

回答数 0

问题

V3版API 签名机制是怎样的?

OpenSearch服务会对每个访问的请求进行身份验证,通过使用Access Key ID和Access Key Secret进行对称加密的方法来验证请求的发送者身份。Access Key ID和Access Key Secr...

轩墨

2019-12-01 20:57:42

1487 浏览量

回答数 0

回答

OpenSearch服务会对每个访问的请求进行身份验证,通过使用Access Key ID和Access Key Secret进行对称加密的方法来验证请求的发送者身份。 Access Key ID和Access Key Secret由阿里云官方颁发给访问者(可以通过阿里云官方网站申请和管理),其中Access Key ID用于标识访问者的身份。 Access Key Secret是用于加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密,只有阿里云和用户知道。 支持应用类型 高级版 标准版 通信协议 只支持 HTTP 协议 请求对应方式 搜索数据必须使用:GET 推送数据必须使用:POST Authorization 字段计算方法 需在 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)) 按照RFC2104的定义,使用上面的用于签名的字符串计算签名HMAC值 签名的方法用 RFC 2104 中定义的 HMAC-SHA1 方法 签名的字符串必须为UTF-8格式 含有中文字符的签名字符串必须先进行UTF-8编码,再与AccessKeySecret计算最终签名 签名参数先后顺序,必须和上面保持一致 参数 描述 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 格式,如2019-02-25T10:09:57Z,时间为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=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 查询请求 请求签名参数 必须 请求 Header 参数 必须 AccessKeySecret 是 Date 是 VERB 是 X-Opensearch-Nonce 是 Date 是 Authorization 是 x-opensearch-nonce 是

canonicalized_resource 是

Header 中的参数值必须要与对应签名方法中的参数值一致 建议将 Content-Md5,Content-Type,Date,CanonicalizedOpenSearchHeaders,Authorization 这些参数都添加到请求Header中,只包含必须参数可能会出现报错,需避免 请求 Header 中包含的参数都必须要参与签名 推送请求 请求签名参数 必须 请求 Header 参数 必须 AccessKeySecret 是 Content-MD5 是 VERB 是 Date 是 Content-MD5 是 Authorization 是 Date 是

canonicalized_resource 是

Header 中的参数值必须要与对应签名方法中的参数值一致 理论上 Content-Md5,Content-Type,Date,CanonicalizedOpenSearchHeaders,Authorization 这些参数都需要添加到请求Header中,只包含必须参数可能会出现报错,需避免 请求 Header 中包含的参数都必须要参与签名 构建CanonicalizedOpenSearchHeaders的方法 所有以 X-Opensearch- 为前缀的 Http专有 Header 被称为 CanonicalizedOpenSearchHeaders,其他非 Http专有 Header 将不被纳入验证 将所有以 X-Opensearch- 为前缀的Http专有 Header 对应的内容补齐,例如X-Opensearch-Nonce : 1551089397451704(该Nonce参数值,可由10位时间戳+6位随机值(100000~999999)组合而成,例如1551089397451704),再去除所有值为空的Http专有 Header 将这些有对应内容值的Http专有 Header 按照名称的字典序进行升序排序 再将这些排序后的专有 Header名,全部转换成小写字母,例如将 X-Opensearch-Nonce : 1551089397451704 转换成 x-opensearch-nonce : 1551089397451704 删除请求头和内容之间分隔符两端出现的任何空格。例如该 x-opensearch-nonce : 1551089397451704 参数,删除两端空格后为:x-opensearch-nonce:1551089397451704 最后将每个请求头及对应内容作为一个单位项,再将每一项之间用 \n 连接拼成最后的 CanonicalizedOpenSearchHeaders,注意最后一个也要有 \n 注意: 若查询请求Header中不包含此处Http专有 Header,即该参数中一个Http专有 Header都没有,则无需 \n,只需在签名方法中去掉该CanonicalizedOpenSearchHeaders签名参数即可,该参数不参与签名计算。 将Http专有 Header添加到Header中时,不能是转换后的小写形式,需按原格式显示 构建CanonicalizedResource的方法 签名的字符串必须为UTF-8格式,且含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret 计算最终签名 查询 CanonicalizedResource = path + ? + query 推送 CanonicalizedResource = path 构建 path 部分 对 path 进行urlencode后,再替换 %2F 为 /,下面的app_schema_demo需替换为自己应用名,常见 path 如下所示 search查询path /v3/openapi/apps/app_schema_demo/search suggest查询path /v3/openapi/apps/app_schema_demo/suggest/suggest/search 最终查询指定应用信息查询请求串,下面“appid”需替换为待查询的应用ID,需包含Authorization授权签名参数(无需指定查询参数) /v3/openapi/apps/appid 推送数据path(tab 是要推送到应用中的某个具体表名,也需替换为自己应用表名) /v3/openapi/apps/app_schema_demo/tab/actions/bulk 构建 query 部分 query 部分由查询参数构成,参数为键值对形式 为需要指定的查询参数设置对应的参数值,并去掉value为空的参数(value为空的参数不计算签名) 再对每一个参数按照先比较参数名后比较参数值的顺序,按照字典升序 再对每一部分的参数名和参数值进行 urlencode,再将参数名和对应参数值之间通过=拼接 再将各个查询参数之间用 & 分割拼接并存储到 query 字符串中 再将该 query 字符串中的+字符,替换成%20。注意如果有&&字符,也需替换成&&。 最后按照 path + ? + query 方式拼接至CanonicalizedResource字符串中,即完成查询操作CanonicalizedResource参数构建,示例如下: /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 以上请求串中主要包含的参数及参数值描述如下: fetch_fields=name 以上请求串中主要包含的query参数中各子句及参数值描述如下(第一个是query参数,第二个是query子句及其它相关子句): query=query=name:'文档'&&sort=id&&config=format:fulljson 注意: query参数中各个查询子句之间必须要用 && 进行拼接 若为推送操作,则只需将 path 部分拼接至 CanonicalizedResource 字符串中即可 构建 Authorization 字段 构建方法参考开头部分描述,需添加到请求 Header 中。假如AccessKeyId 为LTAItQcybixtR9A0,Signature为 1P7tfEh+CU5kFYRXzZ14kkJUAMc=,则python3示例代码大致如下:

headers['Authorization'] = 'OPENSEARCH ' + 'LTAItQcybixtR9A0' + ':' + '1P7tfEh+CU5kFYRXzZ14kkJUAMc=' 签名示例 假如参数值如下 Authorization值为OPENSEARCH LTAItQcybixtR9A0:1P7tfEh+CU5kFYRXzZ14kkJUAMc= AccessKeySecret值为 R0OGKsMj0etgyA9nZM5ykhMqHXBfKG 请求方式为GET Content-MD5值为空,此处作为查询请求 Content-Type值为application/json Date值为2019-02-25T10:09:57Z CanonicalizedOpenSearchHeaders值为x-opensearch-nonce:1551089397451704 CanonicalizedResource值为/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 请求Header 签名字符串计算公式 签名字符串 ‘Content-MD5’: ‘’, ‘Content-Type’: ‘application/json’, ‘Authorization’: ‘OPENSEARCH LTAItQcybixtR9A0:1P7tfEh+CU5kFYRXzZ14kkJUAMc=’, ‘X-Opensearch-Nonce’: ‘1551089397451704’, ‘Date’: ‘2019-02-25T10:09:57Z’ Signature = base64(hmac-sha1( AccessKeySecret, VERB + “\n” + Content-Md5 + “\n” + Content-Type + “\n” + Date + “\n” + CanonicalizedOpenSearchHeaders + CanonicalizedResource)) 1P7tfEh+CU5kFYRXzZ14kkJUAMc= , GET\n \n application/json\n 2019-02-25T10:09:57Z\n x-opensearch-nonce:1551089397451704\n /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 注意: 请求Header中参数值需与签名方法中对应参数值保持一致 可用以下方法计算签名(Signature) 以 hash_hmac 和 base64_encode 编码生成加密值作为Signature python3 示例代码:

import hmac import base64

signature_string = '\n'.join(['GET', '', 'application/json', '2019-02-25T10:09:57Z', 'x-opensearch-nonce:1551089397451704', '/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson'])

signature_hmac = hmac.new('R0OGKsMj0etgyA9nZM5ykhMqHXBfKG'.encode('utf-8'), signature_string.encode('utf-8'), 'sha1') signature = base64.b64encode(signature_hmac.digest()) 假如AccessKeySecret值为 R0OGKsMj0etgyA9nZM5ykhMqHXBfKG 那么通过上面的签名方法构造出来的签名值为 1P7tfEh+CU5kFYRXzZ14kkJUAMc= 构建请求串 请求串 = host + CanonicalizedResource 需在 HTTP 请求 Header 头信息中增加 Authorization(授权)来包含签名(Signature)信息,表明该请求已被授权,同时Header中也需要包含上面提到的这些相关的请求Header。(host为应用访问API地址) 最终search查询请求串 http://host/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 最终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 v3API签名Demo 目前已对外公开 v3版官方Java SDK 和 PHP SDK,且PHP SDK已包含v3API签名过程实现源码,直接调用这些方法即可使用,也可参考 PHP SDK 签名实现过程源码,或参考本文档v3API签名过程来实现其它语言SDK。 因目前OpenSearch官方,没有正式对外提供官方的 python版 和 C#版 SDK,为方便用户参考实现该文档描述签名过程,此处提供 python及C#版查询和推送签名Demo,以供用户参考实现本文档签名操作。 注意: 此处提供 Demo 仅供参考,后续用户参考此 Demo 实现的 SDK 由用户自己维护。

保持可爱mmm

2020-03-26 21:56:35

0 浏览量

回答数 0

回答

OpenSearch服务会对每个访问的请求进行身份验证,通过使用Access Key ID和Access Key Secret进行对称加密的方法来验证请求的发送者身份。 Access Key ID和Access Key Secret由阿里云官方颁发给访问者(可以通过阿里云官方网站申请和管理),其中Access Key ID用于标识访问者的身份。 Access Key Secret是用于加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密,只有阿里云和用户知道。 支持应用类型 高级版 标准版 通信协议 只支持 HTTP 协议 请求对应方式 搜索数据必须使用:GET 推送数据必须使用:POST Authorization 字段计算方法 需在 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)) 按照RFC2104的定义,使用上面的用于签名的字符串计算签名HMAC值 签名的方法用 RFC 2104 中定义的 HMAC-SHA1 方法 签名的字符串必须为UTF-8格式 含有中文字符的签名字符串必须先进行UTF-8编码,再与AccessKeySecret计算最终签名 签名参数先后顺序,必须和上面保持一致 参数 描述 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 格式,如2019-02-25T10:09:57Z,时间为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=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 查询请求 请求签名参数 必须 请求 Header 参数 必须 AccessKeySecret 是 Date 是 VERB 是 X-Opensearch-Nonce 是 Date 是 Authorization 是 x-opensearch-nonce 是

canonicalized_resource 是

Header 中的参数值必须要与对应签名方法中的参数值一致 建议将 Content-Md5,Content-Type,Date,CanonicalizedOpenSearchHeaders,Authorization 这些参数都添加到请求Header中,只包含必须参数可能会出现报错,需避免 请求 Header 中包含的参数都必须要参与签名 推送请求 请求签名参数 必须 请求 Header 参数 必须 AccessKeySecret 是 Content-MD5 是 VERB 是 Date 是 Content-MD5 是 Authorization 是 Date 是

canonicalized_resource 是

Header 中的参数值必须要与对应签名方法中的参数值一致 理论上 Content-Md5,Content-Type,Date,CanonicalizedOpenSearchHeaders,Authorization 这些参数都需要添加到请求Header中,只包含必须参数可能会出现报错,需避免 请求 Header 中包含的参数都必须要参与签名 构建CanonicalizedOpenSearchHeaders的方法 所有以 X-Opensearch- 为前缀的 Http专有 Header 被称为 CanonicalizedOpenSearchHeaders,其他非 Http专有 Header 将不被纳入验证 将所有以 X-Opensearch- 为前缀的Http专有 Header 对应的内容补齐,例如X-Opensearch-Nonce : 1551089397451704(该Nonce参数值,可由10位时间戳+6位随机值(100000~999999)组合而成,例如1551089397451704),再去除所有值为空的Http专有 Header 将这些有对应内容值的Http专有 Header 按照名称的字典序进行升序排序 再将这些排序后的专有 Header名,全部转换成小写字母,例如将 X-Opensearch-Nonce : 1551089397451704 转换成 x-opensearch-nonce : 1551089397451704 删除请求头和内容之间分隔符两端出现的任何空格。例如该 x-opensearch-nonce : 1551089397451704 参数,删除两端空格后为:x-opensearch-nonce:1551089397451704 最后将每个请求头及对应内容作为一个单位项,再将每一项之间用 \n 连接拼成最后的 CanonicalizedOpenSearchHeaders,注意最后一个也要有 \n 注意: 若查询请求Header中不包含此处Http专有 Header,即该参数中一个Http专有 Header都没有,则无需 \n,只需在签名方法中去掉该CanonicalizedOpenSearchHeaders签名参数即可,该参数不参与签名计算。 将Http专有 Header添加到Header中时,不能是转换后的小写形式,需按原格式显示 构建CanonicalizedResource的方法 签名的字符串必须为UTF-8格式,且含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret 计算最终签名 查询 CanonicalizedResource = path + ? + query 推送 CanonicalizedResource = path 构建 path 部分 对 path 进行urlencode后,再替换 %2F 为 /,下面的app_schema_demo需替换为自己应用名,常见 path 如下所示 search查询path /v3/openapi/apps/app_schema_demo/search suggest查询path /v3/openapi/apps/app_schema_demo/suggest/suggest/search 最终查询指定应用信息查询请求串,下面“appid”需替换为待查询的应用ID,需包含Authorization授权签名参数(无需指定查询参数) /v3/openapi/apps/appid 推送数据path(tab 是要推送到应用中的某个具体表名,也需替换为自己应用表名) /v3/openapi/apps/app_schema_demo/tab/actions/bulk 构建 query 部分 query 部分由查询参数构成,参数为键值对形式 为需要指定的查询参数设置对应的参数值,并去掉value为空的参数(value为空的参数不计算签名) 再对每一个参数按照先比较参数名后比较参数值的顺序,按照字典升序 再对每一部分的参数名和参数值进行 urlencode,再将参数名和对应参数值之间通过=拼接 再将各个查询参数之间用 & 分割拼接并存储到 query 字符串中 再将该 query 字符串中的+字符,替换成%20。注意如果有&&字符,也需替换成&&。 最后按照 path + ? + query 方式拼接至CanonicalizedResource字符串中,即完成查询操作CanonicalizedResource参数构建,示例如下: /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 以上请求串中主要包含的参数及参数值描述如下: fetch_fields=name 以上请求串中主要包含的query参数中各子句及参数值描述如下(第一个是query参数,第二个是query子句及其它相关子句): query=query=name:'文档'&&sort=id&&config=format:fulljson 注意: query参数中各个查询子句之间必须要用 && 进行拼接 若为推送操作,则只需将 path 部分拼接至 CanonicalizedResource 字符串中即可 构建 Authorization 字段 构建方法参考开头部分描述,需添加到请求 Header 中。假如AccessKeyId 为LTAItQcybixtR9A0,Signature为 1P7tfEh+CU5kFYRXzZ14kkJUAMc=,则python3示例代码大致如下:

headers['Authorization'] = 'OPENSEARCH ' + 'LTAItQcybixtR9A0' + ':' + '1P7tfEh+CU5kFYRXzZ14kkJUAMc=' 签名示例 假如参数值如下 Authorization值为OPENSEARCH LTAItQcybixtR9A0:1P7tfEh+CU5kFYRXzZ14kkJUAMc= AccessKeySecret值为 R0OGKsMj0etgyA9nZM5ykhMqHXBfKG 请求方式为GET Content-MD5值为空,此处作为查询请求 Content-Type值为application/json Date值为2019-02-25T10:09:57Z CanonicalizedOpenSearchHeaders值为x-opensearch-nonce:1551089397451704 CanonicalizedResource值为/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 请求Header 签名字符串计算公式 签名字符串 ‘Content-MD5’: ‘’, ‘Content-Type’: ‘application/json’, ‘Authorization’: ‘OPENSEARCH LTAItQcybixtR9A0:1P7tfEh+CU5kFYRXzZ14kkJUAMc=’, ‘X-Opensearch-Nonce’: ‘1551089397451704’, ‘Date’: ‘2019-02-25T10:09:57Z’ Signature = base64(hmac-sha1( AccessKeySecret, VERB + “\n” + Content-Md5 + “\n” + Content-Type + “\n” + Date + “\n” + CanonicalizedOpenSearchHeaders + CanonicalizedResource)) 1P7tfEh+CU5kFYRXzZ14kkJUAMc= , GET\n \n application/json\n 2019-02-25T10:09:57Z\n x-opensearch-nonce:1551089397451704\n /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 注意: 请求Header中参数值需与签名方法中对应参数值保持一致 可用以下方法计算签名(Signature) 以 hash_hmac 和 base64_encode 编码生成加密值作为Signature python3 示例代码:

import hmac import base64

signature_string = '\n'.join(['GET', '', 'application/json', '2019-02-25T10:09:57Z', 'x-opensearch-nonce:1551089397451704', '/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson'])

signature_hmac = hmac.new('R0OGKsMj0etgyA9nZM5ykhMqHXBfKG'.encode('utf-8'), signature_string.encode('utf-8'), 'sha1') signature = base64.b64encode(signature_hmac.digest()) 假如AccessKeySecret值为 R0OGKsMj0etgyA9nZM5ykhMqHXBfKG 那么通过上面的签名方法构造出来的签名值为 1P7tfEh+CU5kFYRXzZ14kkJUAMc= 构建请求串 请求串 = host + CanonicalizedResource 需在 HTTP 请求 Header 头信息中增加 Authorization(授权)来包含签名(Signature)信息,表明该请求已被授权,同时Header中也需要包含上面提到的这些相关的请求Header。(host为应用访问API地址) 最终search查询请求串 http://host/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did&&config%3Dformat%3Afulljson 最终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 v3API签名Demo 目前已对外公开 v3版官方Java SDK 和 PHP SDK,且PHP SDK已包含v3API签名过程实现源码,直接调用这些方法即可使用,也可参考 PHP SDK 签名实现过程源码,或参考本文档v3API签名过程来实现其它语言SDK。 因目前OpenSearch官方,没有正式对外提供官方的 python版 和 C#版 SDK,为方便用户参考实现该文档描述签名过程,此处提供 python及C#版查询和推送签名Demo,以供用户参考实现本文档签名操作。 注意: 此处提供 Demo 仅供参考,后续用户参考此 Demo 实现的 SDK 由用户自己维护。

保持可爱mmm

2020-03-26 21:56:23

0 浏览量

回答数 0

问题

鉴权代码示例

概述

URL鉴权规则请查阅

URL鉴权文档,通过这个 demo 您可以根据业务需要,方便的对URL进行鉴权处理。以下Python Demo包含三种鉴权方式:A鉴权方式、B鉴权方式、C鉴权方式&...

青衫无名

2019-12-01 22:08:01

2143 浏览量

回答数 0

问题

python 类的实例方法如何调用和修改类属性

# 定义三个类,一个子类继承两个父类

class R(object):

# 类的属性

def __init__(self):

self.name = '父类R'

...

游客qe5rbsqvahefm

2020-10-28 14:11:22

4 浏览量

回答数 0

问题

云服务器 ECS YUM 在线安装软件方法和常见问题处理

YUM 在线安装软件方法

1、通过如下格式指令进行软件的安装:

yum install -y

操作示例:

2、通过如下格式指令进行软件卸载:

yum rem...

boxti

2019-12-01 22:02:32

2644 浏览量

回答数 0

回答

#!/usr/bin/python

# -*- coding: UTF-8 -*-

if __name__ == '__main__':

a = 0x77

b = a & 3

print 'a & b = %d' % b

b &= 7

print 'a & b = %d' % b

以上实例输出结果为:

a & b = 3

a & b = 3

珍宝珠

2019-12-02 03:18:05

0 浏览量

回答数 0

问题

python获取access数据库中的数据?报错

import win32com.client           conn=win32com.client.Dispatch('ADODB.Connection') DSN='PROVIDER=...

爱吃鱼的程序员

2020-06-08 13:30:46

0 浏览量

回答数 1

回答

print函数是python语言中的一个输出函数,可以输出以下几种内容字符串和数值类型 可以直接输出print( 1)1print( "Hello World")Hello World 2.变量无论什么类型,数值,布尔,列表,字典...都可以直接输出x = 12 print(x)12s = 'Hello' print(s)HelloL = [ 1, 2, 'a'] print(L)[ 1, 2, 'a']t = ( 1, 2, 'a') print(t)( 1, 2, 'a')d = { 'a': 1, 'b': 2} print(d){ 'a': 1, 'b': 2} 3.格式化输出类似于C中的 printfs'Hello'x = len(s) print( "The length of %s is %d" % (s,x) )The length of Hello is 5 【注意】Python2和3的print函数格式不同,3要求加括号(print())缩进最好使用4个空格

xuning715

2019-12-02 01:10:22

0 浏览量

回答数 0

回答

print函数是python语言中的一个输出函数,可以输出以下几种内容字符串和数值类型 可以直接输出print( 1)1print( "Hello World")Hello World 2.变量无论什么类型,数值,布尔,列表,字典...都可以直接输出x = 12 print(x)12s = 'Hello' print(s)HelloL = [ 1, 2, 'a'] print(L)[ 1, 2, 'a']t = ( 1, 2, 'a') print(t)( 1, 2, 'a')d = { 'a': 1, 'b': 2} print(d){ 'a': 1, 'b': 2} 3.格式化输出类似于C中的 printfs'Hello'x = len(s) print( "The length of %s is %d" % (s,x) )The length of Hello is 5 【注意】Python2和3的print函数格式不同,3要求加括号(print())缩进最好使用4个空格

半指温柔乐

2019-12-02 01:09:39

0 浏览量

回答数 0

回答

方法一

#!/usr/bin/python

# -*- coding: UTF-8 -*-

n = 0

s = 0

t = 1

for n in range(1,21):

t *= n

s += t

print '1! + 2! + 3! + ... + 20! = %d' % s

方法二

#!/usr/bin/python

# -*- coding: UTF-8 -*-

s = 0

l = range(1,21)

def op(x):

r = 1

for i in range(1,x + 1):

r *= i

return r

s = sum(map(op,l))

print '1! + 2! + 3! + ... + 20! = %d' % s

以上实例输出结果为:

1! + 2! + 3! + ... + 20! = 2561327494111820313

珍宝珠

2019-12-02 03:17:58

0 浏览量

回答数 0

回答

Python常见数据结构整理

Python中常见的数据结构可以统称为容器(container)。序列(如列表和元组)、映射(如字典)以及集合(set)是三类主要的容器。

一、序列(列表、元组和字符串)

序列中的每个元素都有自己的编号。Python中有6种内建的序列。其中列表和元组是最常见的类型。其他包括字符串、Unicode字符串、buffer对象和xrange对象。下面重点介绍下列表、元组和字符串。

1、列表

列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能。

(1)、创建

通过下面的方式即可创建一个列表:

1

2

3

4

list1=['hello','world']

print list1

list2=[1,2,3]

print list2

输出:

['hello', 'world']

[1, 2, 3]

可以看到,这中创建方式非常类似于javascript中的数组。

(2)、list函数

通过list函数(其实list是一种类型而不是函数)对字符串创建列表非常有效:

1

2

list3=list("hello")

print list3

输出:

['h', 'e', 'l', 'l', 'o']

2、元组

元组与列表一样,也是一种序列,唯一不同的是元组不能被修改(字符串其实也有这种特点)。

(1)、创建

1

2

3

4

5

6

t1=1,2,3

t2="jeffreyzhao","cnblogs"

t3=(1,2,3,4)

t4=()

t5=(1,)

print t1,t2,t3,t4,t5

输出:

(1, 2, 3) ('jeffreyzhao', 'cnblogs') (1, 2, 3, 4) () (1,)

从上面我们可以分析得出:

a、逗号分隔一些值,元组自动创建完成;

b、元组大部分时候是通过圆括号括起来的;

c、空元组可以用没有包含内容的圆括号来表示;

d、只含一个值的元组,必须加个逗号(,);

(2)、tuple函数

tuple函数和序列的list函数几乎一样:以一个序列(注意是序列)作为参数并把它转换为元组。如果参数就算元组,那么该参数就会原样返回:

1

2

3

4

5

6

7

8

t1=tuple([1,2,3])

t2=tuple("jeff")

t3=tuple((1,2,3))

print t1

print t2

print t3

t4=tuple(123)

print t45

输出:

(1, 2, 3)

('j', 'e', 'f', 'f')

(1, 2, 3)

Traceback (most recent call last):

File "F:\Python\test.py", line 7, in

t4=tuple(123)

TypeError: 'int' object is not iterable

3、字符串

(1)创建

1

2

3

4

5

str1='Hello world'

print str1

print str1[0]

for c in str1:

print c

输出:

Hello world

H

H

e

l

l

o

w

o

r

l

d

(2)格式化

字符串格式化使用字符串格式化操作符即百分号%来实现。

1

2

str1='Hello,%s' % 'world.'

print str1

格式化操作符的右操作数可以是任何东西,如果是元组或者映射类型(如字典),那么字符串格式化将会有所不同。

1

2

3

4

5

6

strs=('Hello','world') #元组

str1='%s,%s' % strs

print str1

d={'h':'Hello','w':'World'} #字典

str1='%(h)s,%(w)s' % d

print str1

输出:

Hello,world

Hello,World

注意:如果需要转换的元组作为转换表达式的一部分存在,那么必须将它用圆括号括起来:

1

2

str1='%s,%s' % 'Hello','world'

print str1

输出:

Traceback (most recent call last):

File "F:\Python\test.py", line 2, in

str1='%s,%s' % 'Hello','world'

TypeError: not enough arguments for format string

如果需要输出%这个特殊字符,毫无疑问,我们会想到转义,但是Python中正确的处理方式如下:

1

2

str1='%s%%' % 100

print str1

输出:100%

对数字进行格式化处理,通常需要控制输出的宽度和精度:

1

2

3

4

5

6

7

from math import pi

str1='%.2f' % pi #精度2

print str1

str1='%10f' % pi #字段宽10

print str1

str1='%10.2f' % pi #字段宽10,精度2

print str1

输出:

3.14

3.141593

3.14

字符串格式化还包含很多其他丰富的转换类型,可参考官方文档。

Python中在string模块还提供另外一种格式化值的方法:模板字符串。它的工作方式类似于很多UNIX Shell里的变量替换,如下所示:

1

2

3

4

from string import Template

str1=Template('$x,$y!')

str1=str1.substitute(x='Hello',y='world')

print str1

输出:

Hello,world!

如果替换字段是单词的一部分,那么参数名称就必须用括号括起来,从而准确指明结尾:

1

2

3

4

from string import Template

str1=Template('Hello,w${x}d!')

str1=str1.substitute(x='orl')

print str1

输出:

Hello,world!

如要输出符,可以使用$输出:

1

2

3

4

from string import Template

str1=Template('$x$$')

str1=str1.substitute(x='100')

print str1

输出:100$

除了关键字参数之外,模板字符串还可以使用字典变量提供键值对进行格式化:

1

2

3

4

5

from string import Template

d={'h':'Hello','w':'world'}

str1=Template('$h,$w!')

str1=str1.substitute(d)

print str1

输出:

Hello,world!

除了格式化之外,Python字符串还内置了很多实用方法,可参考官方文档,这里不再列举。

4、通用序列操作(方法)

从列表、元组以及字符串可以“抽象”出序列的一些公共通用方法(不是你想像中的CRUD),这些操作包括:索引(indexing)、分片(sliceing)、加(adding)、乘(multiplying)以及检查某个元素是否属于序列的成员。除此之外,还有计算序列长度、最大最小元素等内置函数。

(1)索引

1

2

3

4

5

6

str1='Hello'

nums=[1,2,3,4]

t1=(123,234,345)

print str1[0]

print nums[1]

print t1[2]

输出

H

2

345

索引从0(从左向右)开始,所有序列可通过这种方式进行索引。神奇的是,索引可以从最后一个位置(从右向左)开始,编号是-1:

1

2

3

4

5

6

str1='Hello'

nums=[1,2,3,4]

t1=(123,234,345)

print str1[-1]

print nums[-2]

print t1[-3]

输出:

o

3

123

(2)分片

分片操作用来访问一定范围内的元素。分片通过冒号相隔的两个索引来实现:

1

2

3

4

5

6

7

8

nums=range(10)

print nums

print nums[1:5]

print nums[6:10]

print nums[1:]

print nums[-3:-1]

print nums[-3:] #包括序列结尾的元素,置空最后一个索引

print nums[:] #复制整个序列

输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[1, 2, 3, 4]

[6, 7, 8, 9]

[1, 2, 3, 4, 5, 6, 7, 8, 9]

[7, 8]

[7, 8, 9]

不同的步长,有不同的输出:

1

2

3

4

5

6

7

8

nums=range(10)

print nums

print nums[0:10] #默认步长为1 等价于nums[1:5:1]

print nums[0:10:2] #步长为2

print nums[0:10:3] #步长为3

##print nums[0:10:0] #步长为0

print nums[0:10:-2] #步长为-2

输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 2, 4, 6, 8]

[0, 3, 6, 9]

[]

(3)序列相加

1

2

3

4

5

6

7

str1='Hello'

str2=' world'

print str1+str2

num1=[1,2,3]

num2=[2,3,4]

print num1+num2

print str1+num1

输出:

Hello world

[1, 2, 3, 2, 3, 4]

Traceback (most recent call last):

File "F:\Python\test.py", line 7, in

print str1+num1

TypeError: cannot concatenate 'str' and 'list' objects

(4)乘法

1

2

3

4

5

6

print [None]*10

str1='Hello'

print str1*2

num1=[1,2]

print num1*2

print str1*num1

输出:

[None, None, None, None, None, None, None, None, None, None]

HelloHello

[1, 2, 1, 2]

Traceback (most recent call last):

File "F:\Python\test.py", line 5, in

print str1*num1

TypeError: can't multiply sequence by non-int of type 'list'

(5)成员资格

in运算符会用来检查一个对象是否为某个序列(或者其他类型)的成员(即元素):

1

2

3

4

5

str1='Hello'

print 'h' in str1

print 'H' in str1

num1=[1,2]

print 1 in num1

输出:

False

True

True

(6)长度、最大最小值

通过内建函数len、max和min可以返回序列中所包含元素的数量、最大和最小元素。

1

2

3

4

5

6

7

8

str1='Hello'

print len(str1)

print max(str1)

print min(str1)

num1=[1,2,1,4,123]

print len(num1)

print max(num1)

print min(num1)

输出:

5

o

H

5

123

1

二、映射(字典)

映射中的每个元素都有一个名字,如你所知,这个名字专业的名称叫键。字典(也叫散列表)是Python中唯一内建的映射类型。

1、键类型

字典的键可以是数字、字符串或者是元组,键必须唯一。在Python中,数字、字符串和元组都被设计成不可变类型,而常见的列表以及集合(set)都是可变的,所以列表和集合不能作为字典的键。键可以为任何不可变类型,这正是Python中的字典最强大的地方。

1

2

3

4

5

6

7

8

list1=["hello,world"]

set1=set([123])

d={}

d[1]=1

print d

d[list1]="Hello world."

d[set1]=123

print d

输出:

{1: 1}

Traceback (most recent call last):

File "F:\Python\test.py", line 6, in

d[list1]="Hello world."

TypeError: unhashable type: 'list'

2、自动添加

即使键在字典中并不存在,也可以为它分配一个值,这样字典就会建立新的项。

3、成员资格

表达式item in d(d为字典)查找的是键(containskey),而不是值(containsvalue)。

Python字典强大之处还包括内置了很多常用操作方法,可参考官方文档,这里不再列举。

思考:根据我们使用强类型语言的经验,比如C#和Java,我们肯定会问Python中的字典是线程安全的吗。

三、集合

集合(Set)在Python 2.3引入,通常使用较新版Python可直接创建,如下所示:

strs=set(['jeff','wong','cnblogs'])

nums=set(range(10))

看上去,集合就是由序列(或者其他可迭代的对象)构建的。集合的几个重要特点和方法如下:

1、副本是被忽略的

集合主要用于检查成员资格,因此副本是被忽略的,如下示例所示,输出的集合内容是一样的。

1

2

3

4

5

set1=set([0,1,2,3,0,1,2,3,4,5])

print set1

set2=set([0,1,2,3,4,5])

print set2

输出如下:

set([0, 1, 2, 3, 4, 5])

set([0, 1, 2, 3, 4, 5])

2、集合元素的顺序是随意的

这一点和字典非常像,可以简单理解集合为没有value的字典。

1

2

strs=set(['jeff','wong','cnblogs'])

print strs

输出如下:

set(['wong', 'cnblogs', 'jeff'])

琴瑟

2019-12-02 01:22:27

0 浏览量

回答数 0

回答

SWIG是Simplified Wrapper and Interface Generator的缩写。是Python中调用C代码的另一种方法。在这个方法中,开发人员必须编写一个额外的接口文件来作为SWIG(终端工具)的入口。 Python开发者一般不会采用这种方法,因为大多数情况它会带来不必要的复杂。而当你有一个C/C++代码库需要被多种语言调用时,这将是个非常不错的选择。 示例如下(来自SWIG官网)

```C

#include

double My_variable = 3.0;

int fact(int n) {

if (n <= 1) return 1;

else return n*fact(n-1);

}

int my_mod(int x, int y) {

return (x%y);

}

char *get_time()

{

time_t ltime;

time(&ltime);

return ctime(&ltime);

}

编译它

unix % swig -python example.i

unix % gcc -c example.c example_wrap.c \

-I/usr/local/include/python2.1

unix % ld -shared example.o example_wrap.o -o _example.so

最后,Python的输出

>>> import example

>>> example.fact(5)

120

>>> example.my_mod(7,3)

1

>>> example.get_time()

'Sun Feb 11 23:01:07 1996'

>>>

我们可以看到,使用SWIG确实达到了同样的效果,虽然下了更多的工夫,但如果你的目标是多语言还是很值得的。

montos

2020-04-16 21:25:46

0 浏览量

回答数 0

回答

请求参数排序 按照参数名称的字典顺序对请求中的参数进行排序。(请求参数有:AccessKeyId、Action、Format、JsonStr、RegionId、SignatureMethod、SignatureNonce、SignatureVersion、Timestamp、Version) 对每个请求参数的名称和值进行编码 名称和值要使用UTF-8字符集进行URL编码(需要编码的字段至少包括:JsonStr、Timestamp),URL编码的编码规则是: 对于字符 A-Z、a-z、0-9以及字符“-”、“_”、“.”、“~”不编码; 对于其他字符编码成“%XY”的格式,其中XY是字符对应ASCII码的16进制表示。比如英文的双引号(”)对应的编码是%22 对于扩展的UTF-8字符,编码成“%XY%ZA…”的格式; 需要说明的是英文空格( )要被编码是%20,而不是加号(+)。 注:一般支持URL编码的库(比如Java中的java.net.URLEncoder)都是按照“application/x-www-form-urlencoded”的MIME类型的规则进行编码的。实现时可以借助该方法,把编码后的字符串中加号(+)替换成%20、星号(*)替换成%2A、%7E替换回波浪号(~),即可得到上述规则描述的编码字符串。 参考代码(java):

public String percentEncode(String o) throws UnsupportedEncodingException { return URLEncoder.encode(o, "utf8").replace("+", "%20") .replace("*", "%2A") .replace("%7E", "~"); } 对编码后的参数名称和值使用英文等号(=)进行连接。 将英文等号连接得到的字符串按参数名称的字典顺序依次使用&符号连接,即得到规范化请求字符串。 编码后的字符串( CanonicalizedQueryString )如下: &AccessKeyId=lFKEO3Q10JCIGvNv&Action=GetAudioDataStatus&Format=JSON&JsonStr=%7B%22appKey%22%3A1733149043164104%2C%22taskId%22%3A%22B8578666-7136-49A9-9DA0-3B3732DAFF62%22%7D&RegionId=cn-hangzhou&SignatureMethod=HMAC-SHA1&SignatureNonce=1c550238-8a54-46a0-b8c4-666237b1e399&SignatureVersion=1.0&Timestamp=2018-02-06T08%3A50%3A58Z&Version=2016-08-01 计算签名签名 ( StringToSign )的构造规则为: HTTPMethod + “&” + percentEncode(“/”) + ”&” + percentEncode(CanonicalizedQueryString) 其中, HTTPMethod是提交请求用的HTTP方法,比如:GET、POST。 percentEncode(“/”)是按照URL编码规则对字符“/”进行编码得到的值,即“%2F”。 percentEncode(CanonicalizedQueryString)是对上步中CanonicalizedQueryString的字符串按URL编码规则编码后得到的字符串。 按照RFC2104的定义,使用上面用于签名的字符串计算签名HMAC值。 注意:计算签名时使用的Key就是用户持有的Access Key Secret并加上一个“&”字符(ASCII:38),使用的哈希算法是SHA1。 按照Base64编码规则把上面的HMAC值编码成字符串,即得到签名值(Signature)。 示例代码 Java:

public String signString(String StringToSign, String accessSecret)

{

Mac mac = Mac.getInstance("HmacSHA1");

mac.init(new SecretKeySpec(

accessSecret.getBytes("UTF-8"),"HmacSHA1"));

byte[] signData = mac.doFinal(StringToSign.getBytes("UTF-8"));

return Base64Helper.encode(signData);

}

python2:

import hashlib import string from hashlib import sha1 import base64 import hmac from hmac import new as hmac

def hash_hmac(ac_key, text): h = hmac(ac_key, text, sha1) d = h.digest() print 'd: ' + d return str(d.encode('base64')) python3:

import base64 import hmac from hashlib import sha1

def hash_hmac(code, key, sha1): hmac_code = hmac.new(key.encode(), code.encode(), sha1).digest() return base64.b64encode(hmac_code).decode() 将得到的签名值作为Signature参数添加到请求参数中,即完成对请求签名的过程。 注意:得到的签名值在作为最后的请求参数值提交时,要和其他参数一样,按照RFC3986的规则进行URL编码)。 示例 签名前的请求URL为:

http://qualitycheck.cn-hangzhou.aliyuncs.com/?JsonStr={"appKey":1733149043164104,"taskId":"B8578666-7136-49A9-9DA0-3B3732DAFF62"}&SignatureVersion=1.0 &Action=GetAudioDataStatus&Format=JSON&SignatureNonce=1c550238-8a54-46a0-b8c4-666237b1e399 &Version=2016-08-01&AccessKeyId=testid&SignatureMethod=HMAC-SHA1&RegionId=cn-hangzhou &Timestamp=2018-02-06T08:50:58Z 那么StringToSign为:

GET&%2F&AccessKeyId%3Dtestid&Action%3DGetAudioDataStatus&Format%3DJSON&JsonStr%3D%257B%2522appKey%2522%253A%25221733149043164104%2522%252C%2522taskId%2522%253A%2522B8578666-7136-49A9-9DA0-3B3732DAFF62%2522%257D&RegionId%3Dcn-hangzhou&SignatureMethod%3DHMAC-SHA1&SignatureNonce%3D1c550238-8a54-46a0-b8c4-666237b1e399&SignatureVersion%3D1.0&Timestamp%3D2018-02-06T08%253A50%253A58Z&Version%3D2016-08-01 如使用的Access Key Id是“testid”,Access Key Secret是“testsecret”,用于计算HMAC的Key就是“testsecret&”,则计算得到的签名值是:

MQIWlE70sNCpDsRRKTpOvdQcME8= 签名后的请求URL为(注意增加了Signature参数):

http://qualitycheck.cn-hangzhou.aliyuncs.com/ ?JsonStr={"appKey":1733149043164104,"taskId":"B8578

保持可爱mmm

2020-03-26 22:32:29

0 浏览量

回答数 0

回答

详细解答可以参考官方帮助文档

之前章节只用到了RAM的子账号功能,这些子账号都是可以长期正常使用的,发生泄露之后如果无法及时解除权限的话会很危险。

继续上文的例子,当开发者的app被用户使用之后,用户的数据要上传到OSS的ram-test-app这个Bucket,当app的用户数据很多的时候,需要考虑如何才能安全的授权给众多的app用户上传数据呢,以及如何保证多个用户之间存储的隔离。

类似这种需要临时访问的场景可以使用STS来完成。STS可以指定复杂的策略来对特定的用户进行限制,仅提供最小的权限。

创建角色

继续上一章节的例子,App用户有一个名为ram-test-app的Bucket来保存个人数据。创建角色的步骤如下:

按照上文的流程创建一个子账号ram_test_app,不需要赋予任何权限,因为在扮演角色的时候会自动获得被扮演角色的所有权限。

创建角色。这里创建两个角色,一个用于用户读取等操作,一个用于用户上传文件。

打开访问控制的管理控制台,选择角色管理 > 新建角色。

选择角色类型。这里选择用户角色。

填写类型信息。因为角色是被阿里云账号使用过的,因此选择默认的即可。

配置角色基本信息。

创建完角色之后,角色是没有任何权限的,因此这里和上文所述一样需要新建一个自定义的授权策略。授权策略如下:{

"Version": "1",

"Statement": [

{

"Effect": "Allow",

"Action": [

"oss:ListObjects",

"oss:GetObject"

],

"Resource": [

"acs:oss:*:*:ram-test-app",

"acs:oss:*:*:ram-test-app/*"

]

}

]

}表示对ram-test-app拥有只读权限。

建立完成后,即可在角色管理里面给RamTestAppReadOnly添加上ram-test-app的只读授权。

按照上文同样的方法,建立一个RamTestAppWrite的角色,并且赋予写ram-test-app的自定义授权,授权如下:{

"Version": "1",

"Statement": [

{

"Effect": "Allow",

"Action": [

"oss:DeleteObject",

"oss:ListParts",

"oss:AbortMultipartUpload",

"oss:PutObject"

],

"Resource": [

"acs:oss:*:*:ram-test-app",

"acs:oss:*:*:ram-test-app/*"

]

}

]

}目前新建的两个角色为:RamTestAppReadOnly和RamTestAppWrite,分别表示了对于ram-test-app的读写权限。

临时授权访问

创建了角色之后,接下来就可以使用临时授权来访问OSS了。

准备工作

在正式使用之前,还有一些工作需要完成。扮演角色也是需要授权的,否则任意子账号都可以扮演这些角色会带来不可预计的风险,因此有扮演对应角色需求的子账号需要显式的配置权限。

在授权管理策略中新建两个自定义的授权策略,分别如下:{

"Statement": [

{

"Action": "sts:AssumeRole",

"Effect": "Allow",

"Resource": "acs:ram::1894189769722283:role/ramtestappreadonly"

}

],

"Version": "1"

}使用相同的方法创建另一个自定义授权策略:{

"Statement": [

{

"Action": "sts:AssumeRole",

"Effect": "Allow",

"Resource": "acs:ram::1894189769722283:role/ramtestappwrite"

}

],

"Version": "1"

}这里Resource后面填写的内容表示某个角色ID,角色的ID可以在角色管理 > 角色详情中找到。

将这两个授权赋给ram_test_app这个账号。

使用STS授权访问

现在一切准备就绪,可以正式使用STS来授权访问了。

这里使用一个简单的STS的python命令行工具sts.py。 具体的调用方法如下:

$python ./sts.py AssumeRole RoleArn=acs:ram::1894189769722283:role/ramtestappreadonly RoleSessionName=usr001 Policy='{"Version":"1","Statement":[{"Effect":"Allow","Action":["oss:ListObjects","oss:GetObject"],"Resource":["acs:oss:*:*:ram-test-app","acs:oss:*:*:ram-test-app/*"]}]}' DurationSeconds=1000 --id=id --secret=secret

RoleArn表示的是需要扮演的角色ID,角色的ID可以在角色管理 > 角色详情中找到。

RoleSessionName是一个用来标示临时凭证的名称,一般来说建议使用不同的应用程序用户来区分。

Policy表示的是在扮演角色的时候额外加上的一个权限限制。

DurationSeconds指的是临时凭证的有效期,单位是s,最小为900,最大为3600。

id和secret表示的是需要扮演角色的子账号的AccessKey。

这里需要解释一下Policy,这里传入的Policy是用来限制扮演角色之后的临时凭证的权限。最后临时凭证获得的权限是角色的权限和这里传入的Policy的交集。

在扮演角色的时候传入Policy的原因是为了灵活性,比如上传文件的时候可以根据不同的用户添加对于上传文件路径的限制,这点会在下面的例子展示。

现在我们可以来实际试验一下STS的作用,作为试验用的Bucket,先在控制台向ram-test-app传入一个test.txt的文本,内容为ststest。

首先使用ram_test_app这个子账号直接来访问。请将下面的AccessKey换成自己试验用的AccessKey。

[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd get oss://ram-test-app/test.txt test.txt --host=oss-cn-hangzhou.aliyuncs.com -i oOhue******Frogv -k OmVwFJO3qcT0******FhOYpg3p0KnA

Error Headers:

[('content-length', '229'), ('server', 'AliyunOSS'), ('connection', 'keep-alive'), ('x-oss-request-id', '564A94D444F4D8B2225E4AFE'), ('date', 'Tue, 17 Nov 2015 02:45:40 GMT'), ('content-type', 'application/xml')]

Error Body:

AccessDenied

AccessDenied

564A94D444F4D8B2225E4AFE

ram-test-app.oss-cn-hangzhou.aliyuncs.com

Error Status:

403

get Failed!

[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd put test.txt oss://ram-test-app/test.txt --host=oss-cn-hangzhou.aliyuncs.com -i oOhue******Frogv -k OmVwFJO3qcT0******FhOYpg3p0KnA

100% Error Headers:

[('content-length', '229'), ('server', 'AliyunOSS'), ('connection', 'keep-alive'), ('x-oss-request-id', '564A94E5B1119B445B9F8C3A'), ('date', 'Tue, 17 Nov 2015 02:45:57 GMT'), ('content-type', 'application/xml')]

Error Body:

AccessDenied

AccessDenied

564A94E5B1119B445B9F8C3A

ram-test-app.oss-cn-hangzhou.aliyuncs.com

Error Status:

403

put Failed!

因为ram_test_app这个子账号没有访问权限,因此访问失败。

使用临时授权下载

现在使用STS来下载文件,这里为了简单,传入的Policy和角色的Policy一致,过期时间使用默认的3600s,App的用户假定为usr001。步骤如下:

使用STS来获取临时的凭证。[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$python ./sts.py AssumeRole RoleArn=acs:ram::1894189769722283:role/ramtestappreadonly RoleSessionName=usr001 Policy='{"Version":"1","Statement":[{"Effect":"Allow","Action":["oss:ListObjects","oss:GetObject"],"Resource":["acs:oss:*:*:ram-test-app","acs:oss:*:*:ram-test-app/*"]}]}' --id=oOhue******Frogv --secret=OmVwFJO3qcT0******FhOYpg3p0KnA

https://sts.aliyuncs.com/?SignatureVersion=1.0&Format=JSON&Timestamp=2015-11-17T03%3A07%3A25Z&RoleArn=acs%3Aram%3A%3A1894189769722283%3Arole%2Framtestappreadonly&RoleSessionName=usr001&AccessKeyId=oOhuek56i53Frogv&Policy=%7B%22Version%22%3A%221%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Action%22%3A%5B%22oss%3AListObjects%22%2C%22oss%3AGetObject%22%5D%2C%22Resource%22%3A%5B%22acs%3Aoss%3A%2A%3A%2A%3Aram-test-app%22%2C%22acs%3Aoss%3A%2A%3A%2A%3Aram-test-app%2F%2A%22%5D%7D%5D%7D&SignatureMethod=HMAC-SHA1&Version=2015-04-01&Signature=bshxPZpwRJv5ch3SjaBiXLodwq0%3D&Action=AssumeRole&SignatureNonce=53e1be9c-8cd8-11e5-9b86-008cfa5e4938

{

"AssumedRoleUser": {

"Arn": "acs:ram::1894189769722283:role/ramtestappreadonly/usr001",

"AssumedRoleId": "317446347657426289:usr001"

},

"Credentials": {

"AccessKeyId": "STS.3mQEbNf******wa180Le",

"AccessKeySecret": "B1w7rCbR4dzGwNYJ******3PiPqKZ3gjQhAxb6mB",

"Expiration": "2015-11-17T04:07:25Z",

"SecurityToken": "CAESvAMIARKAASQQUUTSE+7683CGlhdGsv2/di8uI+X1BxG7MDxM5FTd0fp5wpPK/7UctYH2MJ///c4yMN1PUCcEHI1zppCINmpDG2XeNA3OS16JwS6ESmI50sHyWBmsYkCJW15gXnfhz/OK+mSp1bYxlfB33qfgCFe97Ijeuj8RMgqFx0Hny2BzGhhTVFMuM21RRWJOZnR5Yzl1T3dhMTgwTGUiEjMxNzQ0NjM0NzY1NzQyNjI4OSoGdXNyMDAxMJTrgJ2RKjoGUnNhTUQ1QpsBCgExGpUBCgVBbGxvdxI4CgxBY3Rpb25FcXVhbHMSBkFjdGlvbhogCg9vc3M6TGlzdE9iamVjdHMKDW9zczpHZXRPYmplY3QSUgoOUmVzb3VyY2VFcXVhbHMSCFJlc291cmNlGjYKGGFjczpvc3M6KjoqOnJhbS10ZXN0LWFwcAoaYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwLypKEDE4OTQxODk3Njk3MjIyODNSBTI2ODQyWg9Bc3N1bWVkUm9sZVVzZXJgAGoSMzE3NDQ2MzQ3NjU3NDI2Mjg5chJyYW10ZXN0YXBwcmVhZG9ubHk="

},

"RequestId": "8C009F64-F19D-4EC1-A3AD-7A718CD0B49B"

}

使用临时凭证来下载文件,这里sts_token就是上面STS返回的SecurityToken。[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd get oss://ram-test-app/test.txt test.txt --host=oss-cn-hangzhou.aliyuncs.com -i STS.3mQEbNf******wa180Le -k B1w7rCbR4dzGwNYJ******3PiPqKZ3gjQhAxb6mB --sts_token=CAESvAMIARKAASQQUUTSE+7683CGlhdGsv2/di8uI+X1BxG7MDxM5FTd0fp5wpPK/7UctYH2MJ///c4yMN1PUCcEHI1zppCINmpDG2XeNA3OS16JwS6ESmI50sHyWBmsYkCJW15gXnfhz/OK+mSp1bYxlfB33qfgCFe97Ijeuj8RMgqFx0Hny2BzGhhTVFMuM21RRWJOZnR5Yzl1T3dhMTgwTGUiEjMxNzQ0NjM0NzY1NzQyNjI4OSoGdXNyMDAxMJTrgJ2RKjoGUnNhTUQ1QpsBCgExGpUBCgVBbGxvdxI4CgxBY3Rpb25FcXVhbHMSBkFjdGlvbhogCg9vc3M6TGlzdE9iamVjdHMKDW9zczpHZXRPYmplY3QSUgoOUmVzb3VyY2VFcXVhbHMSCFJlc291cmNlGjYKGGFjczpvc3M6KjoqOnJhbS10ZXN0LWFwcAoaYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwLypKEDE4OTQxODk3Njk3MjIyODNSBTI2ODQyWg9Bc3N1bWVkUm9sZVVzZXJgAGoSMzE3NDQ2MzQ3NjU3NDI2Mjg5chJyYW10ZXN0YXBwcmVhZG9ubHk=

100% The object test.txt is downloaded to test.txt, please check.

0.061(s) elapsed

可见已经可以使用临时凭证来下载文件了,那再试着使用这个凭证来上传。[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd put test.txt oss://ram-test-app/test.txt --host=oss-cn-hangzhou.aliyuncs.com -i STS.3mQEbNf******wa180Le -k B1w7rCbR4dzGwNYJ******3PiPqKZ3gjQhAxb6mB --sts_token=CAESvAMIARKAASQQUUTSE+7683CGlhdGsv2/di8uI+X1BxG7MDxM5FTd0fp5wpPK/7UctYH2MJ///c4yMN1PUCcEHI1zppCINmpDG2XeNA3OS16JwS6ESmI50sHyWBmsYkCJW15gXnfhz/OK+mSp1bYxlfB33qfgCFe97Ijeuj8RMgqFx0Hny2BzGhhTVFMuM21RRWJOZnR5Yzl1T3dhMTgwTGUiEjMxNzQ0NjM0NzY1NzQyNjI4OSoGdXNyMDAxMJTrgJ2RKjoGUnNhTUQ1QpsBCgExGpUBCgVBbGxvdxI4CgxBY3Rpb25FcXVhbHMSBkFjdGlvbhogCg9vc3M6TGlzdE9iamVjdHMKDW9zczpHZXRPYmplY3QSUgoOUmVzb3VyY2VFcXVhbHMSCFJlc291cmNlGjYKGGFjczpvc3M6KjoqOnJhbS10ZXN0LWFwcAoaYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwLypKEDE4OTQxODk3Njk3MjIyODNSBTI2ODQyWg9Bc3N1bWVkUm9sZVVzZXJgAGoSMzE3NDQ2MzQ3NjU3NDI2Mjg5chJyYW10ZXN0YXBwcmVhZG9ubHk=

100% Error Headers:

[('content-length', '254'), ('server', 'AliyunOSS'), ('connection', 'keep-alive'), ('x-oss-request-id', '564A9A2A1790CF0F53C15C82'), ('date', 'Tue, 17 Nov 2015 03:08:26 GMT'), ('content-type', 'application/xml')]

Error Body:

AccessDenied

Access denied by authorizer's policy.

564A9A2A1790CF0F53C15C82

ram-test-app.oss-cn-hangzhou.aliyuncs.com

Error Status:

403

put Failed!由于扮演的角色只有下载的权限,因此上传失败。

使用临时授权上传

现在可以来试验一下使用STS上传。步骤如下:

获取STS的临时凭证,App用户为usr001。[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$python ./sts.py AssumeRole RoleArn=acs:ram::1894189769722283:role/ramtestappwrite RoleSessionName=usr001 Policy='{"Version":"1","Statement":[{"Effect":"Allow","Action":["oss:PutObject"],"Resource":["acs:oss:*:*:ram-test-app/usr001/*"]}]}' --id=oOhue******Frogv --secret=OmVwFJO3qcT0******FhOYpg3p0KnA

https://sts.aliyuncs.com/?SignatureVersion=1.0&Format=JSON&Timestamp=2015-11-17T03%3A16%3A10Z&RoleArn=acs%3Aram%3A%3A1894189769722283%3Arole%2Framtestappwrite&RoleSessionName=usr001&AccessKeyId=oOhuek56i53Frogv&Policy=%7B%22Version%22%3A%221%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Action%22%3A%5B%22oss%3APutObject%22%5D%2C%22Resource%22%3A%5B%22acs%3Aoss%3A%2A%3A%2A%3Aram-test-app%2Fusr001%2F%2A%22%5D%7D%5D%7D&SignatureMethod=HMAC-SHA1&Version=2015-04-01&Signature=Y0OPUoL1PrCqX4X6A3%2FJvgXuS6c%3D&Action=AssumeRole&SignatureNonce=8d0798a8-8cd9-11e5-9f49-008cfa5e4938

{

"AssumedRoleUser": {

"Arn": "acs:ram::1894189769722283:role/ramtestappwrite/usr001",

"AssumedRoleId": "355407847660029428:usr001"

},

"Credentials": {

"AccessKeyId": "STS.rtfx13******NlIJlS4U",

"AccessKeySecret": "2fsaM8E2maB2dn******wpsKTyK4ajo7TxFr0zIM",

"Expiration": "2015-11-17T04:16:10Z",

"SecurityToken": "CAESkwMIARKAAUh3/Uzcg13YLRBWxy0IZjGewMpg31ITxCleBFU1eO/3Sgpudid+GVs+Olvu1vXJn6DLcvPa8azKJKtzV0oKSy+mwUrxSvUSRVDntrs78CsNfWoOJUMJKjLIxdWnGi1pgxJCBzNZ2YV/6ycTaZySSE1V6kqQ7A+GPwYoBSnWmLpdGhhTVFMucnRmeDEzRFlNVWJjTmxJSmxTNFUiEjM1NTQwNzg0NzY2MDAyOTQyOCoGdXNyMDAxMOPzoJ2RKjoGUnNhTUQ1QnYKATEacQoFQWxsb3cSJwoMQWN0aW9uRXF1YWxzEgZBY3Rpb24aDwoNb3NzOlB1dE9iamVjdBI/Cg5SZXNvdXJjZUVxdWFscxIIUmVzb3VyY2UaIwohYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwL3VzcjAwMS8qShAxODk0MTg5NzY5NzIyMjgzUgUyNjg0MloPQXNzdW1lZFJvbGVVc2VyYABqEjM1NTQwNzg0NzY2MDAyOTQyOHIPcmFtdGVzdGFwcHdyaXRl"

},

"RequestId": "19407707-54B2-41AD-AAF0-FE87E8870B0D"

}

试验一下能否使用这个凭证来上传下载。[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd get oss://ram-test-app/test.txt test.txt --host=oss-cn-hangzhou.aliyuncs.com -i STS.rtfx13******NlIJlS4U -k 2fsaM8E2maB2dn******wpsKTyK4ajo7TxFr0zIM --sts_token=CAESkwMIARKAAUh3/Uzcg13YLRBWxy0IZjGewMpg31ITxCleBFU1eO/3Sgpudid+GVs+Olvu1vXJn6DLcvPa8azKJKtzV0oKSy+mwUrxSvUSRVDntrs78CsNfWoOJUMJKjLIxdWnGi1pgxJCBzNZ2YV/6ycTaZySSE1V6kqQ7A+GPwYoBSnWmLpdGhhTVFMucnRmeDEzRFlNVWJjTmxJSmxTNFUiEjM1NTQwNzg0NzY2MDAyOTQyOCoGdXNyMDAxMOPzoJ2RKjoGUnNhTUQ1QnYKATEacQoFQWxsb3cSJwoMQWN0aW9uRXF1YWxzEgZBY3Rpb24aDwoNb3NzOlB1dE9iamVjdBI/Cg5SZXNvdXJjZUVxdWFscxIIUmVzb3VyY2UaIwohYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwL3VzcjAwMS8qShAxODk0MTg5NzY5NzIyMjgzUgUyNjg0MloPQXNzdW1lZFJvbGVVc2VyYABqEjM1NTQwNzg0NzY2MDAyOTQyOHIPcmFtdGVzdGFwcHdyaXRl

Error Headers:

[('content-length', '254'), ('server', 'AliyunOSS'), ('connection', 'keep-alive'), ('x-oss-request-id', '564A9C31FFFC811F24B6E7E3'), ('date', 'Tue, 17 Nov 2015 03:17:05 GMT'), ('content-type', 'application/xml')]

Error Body:

AccessDenied

Access denied by authorizer's policy.

564A9C31FFFC811F24B6E7E3

ram-test-app.oss-cn-hangzhou.aliyuncs.com

Error Status:

403

get Failed!

[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd put test.txt oss://ram-test-app/test.txt --host=oss-cn-hangzhou.aliyuncs.com -i STS.rtfx13******NlIJlS4U -k 2fsaM8E2maB2dn******wpsKTyK4ajo7TxFr0zIM --sts_token=CAESkwMIARKAAUh3/Uzcg13YLRBWxy0IZjGewMpg31ITxCleBFU1eO/3Sgpudid+GVs+Olvu1vXJn6DLcvPa8azKJKtzV0oKSy+mwUrxSvUSRVDntrs78CsNfWoOJUMJKjLIxdWnGi1pgxJCBzNZ2YV/6ycTaZySSE1V6kqQ7A+GPwYoBSnWmLpdGhhTVFMucnRmeDEzRFlNVWJjTmxJSmxTNFUiEjM1NTQwNzg0NzY2MDAyOTQyOCoGdXNyMDAxMOPzoJ2RKjoGUnNhTUQ1QnYKATEacQoFQWxsb3cSJwoMQWN0aW9uRXF1YWxzEgZBY3Rpb24aDwoNb3NzOlB1dE9iamVjdBI/Cg5SZXNvdXJjZUVxdWFscxIIUmVzb3VyY2UaIwohYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwL3VzcjAwMS8qShAxODk0MTg5NzY5NzIyMjgzUgUyNjg0MloPQXNzdW1lZFJvbGVVc2VyYABqEjM1NTQwNzg0NzY2MDAyOTQyOHIPcmFtdGVzdGFwcHdyaXRl

100% Error Headers:

[('content-length', '254'), ('server', 'AliyunOSS'), ('connection', 'keep-alive'), ('x-oss-request-id', '564A9C3FB8DE437A91B16772'), ('date', 'Tue, 17 Nov 2015 03:17:19 GMT'), ('content-type', 'application/xml')]

Error Body:

AccessDenied

Access denied by authorizer's policy.

564A9C3FB8DE437A91B16772

ram-test-app.oss-cn-hangzhou.aliyuncs.com

Error Status:

403

put Failed!这里出现了问题,上传test.txt失败了。将本小节开始的时候传入的Policy格式化之后如下:{

"Version": "1",

"Statement": [

{

"Effect": "Allow",

"Action": [

"oss:PutObject"

],

"Resource": [

"acs:oss:*:*:ram-test-app/usr001/*"

]

}

]

}这个Policy的意义是仅允许用户向ram-test-app这个Bucket上传类似usr001/的文件,如果App用户是usr002的时候,就可以修改Policy为仅允许上传类似usr002/这种类型的文件,通过这种对不同的App用户设定不同的Policy的方式,可以做到不同App用户之间拥有独立的存储空间互不干扰的目的。

重新试验,将上传的目标指定为ram-test-app/usr001/test.txt。[admin@NGIS-CWWF344M01C /home/admin/oss_test]

$./osscmd put test.txt oss://ram-test-app/usr001/test.txt --host=oss-cn-hangzhou.aliyuncs.com -i STS.rtfx13******NlIJlS4U -k 2fsaM8E2maB2dn******wpsKTyK4ajo7TxFr0zIM --sts_token=CAESkwMIARKAAUh3/Uzcg13YLRBWxy0IZjGewMpg31ITxCleBFU1eO/3Sgpudid+GVs+Olvu1vXJn6DLcvPa8azKJKtzV0oKSy+mwUrxSvUSRVDntrs78CsNfWoOJUMJKjLIxdWnGi1pgxJCBzNZ2YV/6ycTaZySSE1V6kqQ7A+GPwYoBSnWmLpdGhhTVFMucnRmeDEzRFlNVWJjTmxJSmxTNFUiEjM1NTQwNzg0NzY2MDAyOTQyOCoGdXNyMDAxMOPzoJ2RKjoGUnNhTUQ1QnYKATEacQoFQWxsb3cSJwoMQWN0aW9uRXF1YWxzEgZBY3Rpb24aDwoNb3NzOlB1dE9iamVjdBI/Cg5SZXNvdXJjZUVxdWFscxIIUmVzb3VyY2UaIwohYWNzOm9zczoqOio6cmFtLXRlc3QtYXBwL3VzcjAwMS8qShAxODk0MTg5NzY5NzIyMjgzUgUyNjg0MloPQXNzdW1lZFJvbGVVc2VyYABqEjM1NTQwNzg0NzY2MDAyOTQyOHIPcmFtdGVzdGFwcHdyaXRl

100%

Object URL is: http://ram-test-app.oss-cn-hangzhou.aliyuncs.com/usr001%2Ftest.txt

Object abstract path is: oss://ram-test-app/usr001/test.txt

ETag is "946A0A1AC8245696B9C6A6F35942690B"

0.071(s) elapsed可见上传成功了。

总结

本章主要介绍了使用STS来临时授权用户访问OSS。在典型的移动开发场景中,使用STS可以做到不同的App用户需要访问App的时候,可以通过获取到的临时授权来访问OSS。临时授权可以指定过期时间,因此大大降低了泄露的危害。在获取临时授权的时候,可以根据App用户的不同,传入不同的授权策略来限制用户的访问权限,比如限制用户访问的Object路径,从而达到隔离不同App用户的存储空间的目的。

2019-12-01 23:13:38

0 浏览量

回答数 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值