Skip to content

Instantly share code, notes, and snippets.

@Yxnt
Last active February 4, 2020 13:12
Show Gist options
  • Save Yxnt/39985d7aae6f6a5dcba28acdb54fa1e0 to your computer and use it in GitHub Desktop.
Save Yxnt/39985d7aae6f6a5dcba28acdb54fa1e0 to your computer and use it in GitHub Desktop.
Aliyun STS Signature

阿里云STS相关文档:https://help.aliyun.com/document_detail/28763.html?spm=a2c4g.11186623.6.804.55aa3289dRtm3X

请求参数中policy为临时权限,如果不填写则将会使用角色默认的所有权限,填写的规则见相关服务的STS权限规则,最下方提供一个基本的SLS服务的自定义授权规则

DurationSeconds默认时间为3600秒

脚本的使用方式为:

python3 sign.py

脚本会返回如下内容

{
    "RequestId": "FD5342E4-8AD9-4FCC-B184-F4899A40B7B7",
    "AssumedRoleUser": {
        "AssumedRoleId": "xxxxxxxxxxxxxxxx",
        "Arn": "xxxxxxxxxxxxxxxxxxxxxxx"
    },
    "Credentials": {
        "AccessKeySecret": "xxxxxxxxxxxxxxxxx",
        "AccessKeyId": "STS.xxxxxxxxxxxxxxxxxxx",
        "Expiration": "2020-02-04T14:08:03Z",
        "SecurityToken": "xxxxxxxxxxxxxxxxxxxxxx"
    }
}
import base64
import hmac
import json
import time
from hashlib import sha1
from urllib.parse import quote
import random
import requests
class Sign(object):
FORMAT_ISO_8601 = "%Y-%m-%dT%H:%M:%SZ"
APIVERSION = '2015-04-01'
def __init__(self, ak: str, secret: str, params: dict, method: str):
'''
:param ak: Access id
:param secret: Access secret
:param params: request params
:param method: http method
:param region: aliyun region https://help.aliyun.com/document_detail/40654.html
'''
self._ak = ak
self._secret = "{secret}&".format(secret=secret)
self._method = method
self.params = {
"Format": "JSON",
"Version": self.APIVERSION, # replace
"AccessKeyId": self._ak,
"SignatureMethod": "HMAC-SHA1",
"Timestamp": self.__get_iso_8061_date(),
"SignatureVersion": "1.0",
"SignatureNonce": random.random()
}
self.params.update(params)
self.__sign()
def __get_iso_8061_date(self):
# from Aliyun Core Sdk utils parameter_helper.py
return time.strftime(self.FORMAT_ISO_8601, time.gmtime())
@staticmethod
def __percent_encode(string):
# from Aliyun Core Sdk utils parameter_helper.py
res = quote(string.encode('utf8'), '')
res = res.replace('+', '%20')
res = res.replace('*', '%2A')
res = res.replace('%7E', '~')
return res
def __str_to_sign(self):
'''
https://yq.aliyun.com/articles/79060
https://help.aliyun.com/document_detail/25492.html
:return:
'''
params_s = sorted(self.params.items(), key=lambda x: x[0])
args_list = []
for i in params_s:
key, value = i
if key == "Timestamp" or key == "RoleArn":
value = self.__percent_encode(value)
args_list.append("{key}={value}".format(key=key, value=value))
stand_str = "&".join(args_list)
uri_encode = self.__percent_encode("/")
args_encode = self.__percent_encode(stand_str)
url_encode = "{method}&{uri}&{args}".format(method=self._method, uri=uri_encode, args=args_encode)
return url_encode
def __sign(self):
'''
sha1hmac encrypt
:return:
'''
signstr = hmac.new(bytearray(self._secret, 'utf8'), bytearray(self.__str_to_sign(), 'utf8'),
sha1).digest()
signbase64 = base64.b64encode(signstr).decode().strip()
self.params['Signature'] = signbase64
return self.params
if __name__ == '__main__':
params = {"Action": "AssumeRole",
"RoleArn":"", # replace
"RoleSessionName":"", # random string
"policy": "",
"DurationSeconds":"3600"
}
s = Sign(ak="", secret="",
params=params,
method="GET") # replace ak and secret
resp = requests.get("https://sts.aliyuncs.com", params=s.params)
print(json.dumps(resp.json(),indent=4))
{
"Statement": [
{
"Effect": "Allow",
"Action": [
"log:ListProject",
"log:GetProject"
],
"Resource": "acs:log:*:*:project/*"
},
{
"Effect": "Allow",
"Action": [
"log:GetLogStore",
"log:GetIndex",
"log:GetLogStoreLogs"
],
"Resource": [
"acs:log:*:*:project/这里填写你的project名称/logstore/这里填写授权的logstore,如果授权所有则填写*"
]
}
],
"Version": "1"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment