設置EndPoint和憑證
移動終端是一個不受信任的環境,把AccessKeyId和AccessKeySecret直接保存在終端用來加簽請求,存在極高的風險。建議只在測試時使用明文設置模式,業務應用推薦使用STS鑒權模式或自簽名模式,詳細請參考:訪問控制、移動端直傳。
如果用STS鑒權模式,推薦使用OSSAuthCredentialProvider方式直接訪問鑒權應用服務器,token過期后可以自動更新。
更多信息可查看可查看sample 點擊查看。
設置EndPoint和CredentialProvider示例如下:
NSString *endpoint = "http://oss-cn-hangzhou.aliyuncs.com";//直接訪問鑒權服務器(推薦,token過期后可以自動更新)id<OSSCredentialProvider> credential = [[OSSAuthCredentialProvider alloc] initWithAuthServerUrl:@"鑒權服務器地址,例如http://abc.com"];client = [[OSSClient alloc] initWithEndpoint:endPoint credentialProvider:credential];
提示:
- 更多鑒權方式參考:訪問控制。
初始化_iOS-SDK_SDK 參考_對象存儲 OSS-阿里雲 https://help.aliyun.com/document_detail/32057.html
訪問控制_iOS-SDK_SDK 參考_對象存儲 OSS-阿里雲 https://help.aliyun.com/document_detail/32059.html

使用STS詳細步驟
-
App用戶登錄。
App用戶由您自己管理。您可以自定義身份管理系統,也可以使用外部Web賬號或OpenID。對於每個有效的App用戶來說,AppServer是可以確切地定義出每個App用戶的最小訪問權限。
-
AppServer請求STS服務獲取一個安全令牌(SecurityToken)。
-
在調用STS之前,AppServer需要確定App用戶的最小訪問權限(用Policy語法描述)以及授權的過期時間。
-
通過調用STS的AssumeRole(扮演角色)接口來獲取安全令牌。角色管理與使用相關內容請參考RAM使用指南中的角色管理。
-
-
STS返回給AppServer一個有效的訪問憑證,包括一個安全令牌(SecurityToken)、臨時訪問密鑰(AccessKeyId, AccessKeySecret)以及過期時間。
-
AppServer將訪問憑證返回給ClientApp。
ClientApp可以緩存這個憑證。當憑證失效時,ClientApp需要向AppServer申請新的有效訪問憑證。比如,訪問憑證有效期為1小時,那么ClientApp可以每30分鍾向AppServer請求更新訪問憑證。
-
ClientApp使用本地緩存的訪問憑證去請求Aliyun Service API。雲服務會感知STS訪問憑證,並會依賴STS服務來驗證訪問憑證,並正確響應用戶請求。
注意:使用這種模式授權需要先開通阿里雲RAM服務:單擊查看
-
STS安全令牌詳情請參考RAM使用指南中的角色管理
-
調用STS服務接口AssumeRole來獲取有效訪問憑證即可
-
直接使用STS SDK來調用該方法單擊查看
-
STS使用手冊:單擊查看
-
OSS授權策略配置:單擊查看
-
實戰指南:單擊查看
import json
from flask import Flask, jsonify, abort, make_response, request
import time
from aliyunsdkcore import client
from aliyunsdksts.request.v20150401 import AssumeRoleRequest
def getSts(uid):
# 通過管理控制后台-訪問控制 https://help.aliyun.com/product/28625.html
# RAM控制台 https://ram.console.aliyun.com/
# STS授權相關信息獲取步驟:
# 1.RAM控制台用戶管理創建子用戶(User)同時點擊該用戶創建並獲取AccessKeyID和AccessKeySecret https://help.aliyun.com/document_detail/28637.html
# 2.對該子用戶(User) 授予AliyunSTSAssumeRoleAccess策略(必須),如需自定義策略請看 https://help.aliyun.com/document_detail/28640.html
# 3.RAM控制台角色管理創建角色role,進行自定義授權設置(控制操作的內容),獲取Arn https://help.aliyun.com/document_detail/28649.html
# 注意點:
# 只有子用戶(User)才能調用 AssumeRole 接口
# 阿里雲主用戶(Root User)的AccessKeys不能用於發起AssumeRole請求
# python sdk說明
# 構建一個 Aliyun Client, 用於發起請求
# 構建Aliyun Client時需要設置AccessKeyId和AccessKeySevcret
# STS是Global Service, API入口位於華東 1 (杭州) , 這里Region填寫"cn-hangzhou"
# clt = client.AcsClient('<access-key-id>','<access-key-secret>','cn-hangzhou')
AccessKeyID = "************************"
AccessKeySecret = "************************"
roleArn = "************************"
'''
root
accessKeyId = '1'
accessKeySecret = '2'
'''
'''
//AccessKey詳情
AccessKeyID:
1
AccessKeySecret:
2
'''
kid, ks = '1', '2'
AccessKeyID, AccessKeySecret = kid, ks
roleArn = 'acs:ram::3:role/aliyunosstokengeneratorrole'
clt = client.AcsClient(AccessKeyID, AccessKeySecret, 'cn-hangzhou')
# 構造"AssumeRole"請求
request___ = AssumeRoleRequest.AssumeRoleRequest()
# 指定角色 需要在 RAM 控制台上獲取
request___.set_RoleArn(roleArn)
# RoleSessionName 是臨時Token的會話名稱,自己指定用於標識你的用戶,主要用於審計,或者用於區分Token頒發給誰
# 但是注意RoleSessionName的長度和規則,不要有空格,只能有'-' '.' '@' 字母和數字等字符
# 具體規則請參考API文檔中的格式要求
'''
#AssumeRole_操作接口_API 參考(STS)_訪問控制-阿里雲 https://help.aliyun.com/document_detail/28763.html
RoleSessionName
類型:String
必須:是
描述:用戶自定義參數。此參數用來區分不同的Token,可用於用戶級別的訪問審計。
格式:^[a-zA-Z0-9\.@\-_]+$ 2-32個字符
'''
request___.set_RoleSessionName(uid)
# OSS Policy settings could not set by default
# can read https://help.aliyun.com/document_detail/56288.html
# case https://help.aliyun.com/knowledge_detail/39717.html?spm=5176.product28625.6.735.5etPTf
# case https://help.aliyun.com/knowledge_detail/39712.html?spm=5176.7739717.6.729.aZiRgD
# 發起請求,並得到response
try:
response = clt.do_action_with_exception(request___)
## { "ErrorDump": "the JSON object must be str, not 'bytes'", "StatusCode": "500" }
# text = json.loads(response) win ok linux + .decode('utf-8') 加后 win 依然ok
text = json.loads(response.decode('utf-8'))
stsDict = dict().fromkeys(
['RequestId', 'uid', 'Expiration', 'AccessKeyId', 'AccessKeySecret', 'SecurityToken', 'StatusCode'])
stsDict["RequestId"] = text["RequestId"]
stsDict["uid"] = uid
stsDict['Expiration'] = text["Credentials"]['Expiration']
stsDict["AccessKeyId"] = text["Credentials"]["AccessKeyId"]
stsDict["AccessKeySecret"] = text["Credentials"]["AccessKeySecret"]
stsDict['SecurityToken'] = text["Credentials"]['SecurityToken']
stsDict["StatusCode"] = "200"
# stsText = json.dumps(stsDict)
print('-----------》')
print(stsDict)
print('《-----------')
return stsDict
except Exception as e:
print(e)
# errorDict = dict().fromkeys(['StatusCode', 'ErrorCode', 'ErrorMessage'])
errorDict = dict().fromkeys(['StatusCode', 'ErrorDump'])
errorDict["StatusCode"] = "500"
# errorDict["ErrorMessage"] = e.message
# errorDict["ErrorCode"] = e.error_code
errorDict["ErrorDump"] = '{}'.format(e)
# stsText = json.dumps(errorDict)
return errorDict
# return stsText
pass
aliBridge = Flask(__name__)
aliBridge.config['JSON_AS_ASCII'] = False
@aliBridge.route('/v1.0/aliBridge/aliyunosstokengenerator', methods=['POST'])
def aliyunosstokengeneratorrole():
if not request.json:
abort(400)
chk_k = ['ipv4', 'imei', 'kid', 'ks']
ipv4, imei, kid, ks = request.json['ipv4'], request.json['imei'], request.json['kid'], request.json['ks']
# ipv4, imei, kid, ks = request.json[0:4]
uid = 'ipv4@{}@imei@{}'.format(ipv4, imei)
uid = '{}@{}'.format(ipv4, imei)
# uid ='ipv4__123__imei_123',
if (kid, ks) != ('ourServerKeyId', 'ourServerKeyValue'):
abort(400)
for c in chk_k:
if c not in request.json:
abort(400)
# task = {
# 'uid': request.json['uid'],
# # 'uid': request,
# 'no_open': 12,
# 'no_ad': 34,
# 'description': '該uid在ad_direct_order中共計123條當前未失效,其中12條打不開相應頁面,34條頁面中沒有我司廣告位',
# 'cost_time': 123,
# 'request_time': time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time() - 123)),
# 'current_time': time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time()))
# }
# return jsonify({'status': '1', 'info': task}), 201
task = getSts(uid)
return jsonify(task), 201
'''
{
"ipv4":"197.164.165.154","imei":"123456789012347","kid":"ourServerKeyId","ks":"ourServerKeyValue"
}
'''
if __name__ == '__main__':
aliBridge.run(host='0.0.0.0', port=5001, debug=True)
