モバイルゲームでは、多くのアプリケーションで、開発者はプレーヤーのリソースを分離する必要があります。これには、ファイルの保存からユーザープロファイル情報の処理までさまざまなものが含まれます。従来の方法を使用することで、開発者はこの分離を管理できますが、セキュリティ、スケーラビリティ、API など他の多くの問題も考慮する必要があります。
クラウド技術が進化するにつれて、より高いレベルのユーザビリティと機能の必要性が増しています。Object Storage Service (OSS)を使用すると、顧客はオブジェクトを簡単かつ効率的に保存および管理できます。OSS はリアルタイムの画像処理サービスをオンラインで提供しています。一部のお客様は、OSS のようなサービスへのアクセスを制限するなどの追加機能を必要とするかもしれませんが、安全で集中管理が便利です。
セキュリティトークンサービスは、Alibaba Cloud アカウントまたは RAM ユーザーのための短期アクセス許可管理を提供します。STS を使用すると、ローカルアカウントシステムで管理されているフェデレーションユーザーに、有効期限およびアクセス許可をカスタマイズするアクセス資格情報を発行できます。フェデレーションユーザーは、STS テンポラリアクセスクレデンシャルを使用して Alibaba Cloud サービス API を直接呼び出したり、Alibaba Cloud Management Console にログオンして認証されたリソースにアクセスすることができます。このシナリオでは、OSS を使用して STS の機能をテストします。
前提条件
これには、 Resource Access Management (RAM)の設定と役割を調整する機能が必要です。詳細については、ロールを参照してください。
サンプルコードは Python で書かれています。必須ではありませんが、コンピュータプログラミングの基本的な理解があると有利です。このチュートリアルで提供されているサンプルコードは、特定のニーズに合わせて変更できるテンプレートとして機能します。多くの人々が現在、未加工の API を使用して環境やアプリケーションを管理しています。SDK は多くの言語で利用できますが、未加工の API はより柔軟性があります。
アーキテクチャー
この図では、RAM ユーザーは、OSS バケット内の別のフォルダにイメージをアップロードする必要があります。アップロードプロセスは次のとおりです。
-
ユーザは、AssumeRole を呼び出すことによって、Alibaba Cloud 内の特定のフォルダに対する OSS アクセスの読み取りおよび書き込みのRAM ロールを想定します。
-
STS は、一連の一時的なセキュリティ資格情報を返します。
-
ユーザーは一時的なセキュリティ資格情報を適用して OSS にアクセスします。その後、ユーザーはオブジェクトに対して読み取りまたは書き込み呼び出しを行うことができます。
ここでは例として OSS を取り上げます。ただし、STS は、Alibaba Cloud サービスの広い範囲に一時的にアクセスするために使用できます。このチュートリアルでは、細かいSTSパーミッションを使用して、特定の OSS バケットへのアクセスを制限しています。
実装
サンプルコードの 3 つのファイルは次のとおりです。
- sts.pyこれは、ロールを想定し、accessKeyId、accessKeySecret、および securityToken などの重要な情報を取得するためのコードです。
使用可能な機能は次のとおりです。
- リクエスト信頼性を保証するための署名を生成する
- HTTPS リクエストを取得する
ファイル “sts.py”のサンプルコードは次のとおりです。
from base64 import b64encode
from datetime import datetime
from Crypto.Hash import SHA, HMAC
import md5, httplib, urllib, uuid, json
##### CONFIG MANAGEMENT
accessKeyId = "<access_key_id>"
accessKeySecret = "<access_key_secret>"
##### FUNCTION MANAGEMENT
def generateSignature(accessKeySecret, stringToSign):
hmac = HMAC.new(accessKeySecret, stringToSign, SHA)
return b64encode(hmac.digest())
def getHttpsRequest(host, verb, path):
conn = httplib.HTTPSConnection(host)
conn.request(verb, path)
return conn.getresponse()
# ###### STS MANAGEMENT
host = "sts.aliyuncs.com"
verb = "GET"
bucketName = "<bucket_name>"
folderName = "1"
policy = '{"Statement": [{"Effect": "Allow","Action": ["oss:*"],"Resource": ["acs:oss:*:*:' + bucketName + '/' + folderName + '","acs:oss:*:*:' + bucketName + '/' + folderName + '/*"]}],"Version": "1"}'
dictionaryParams = {
"AccessKeyId": accessKeyId,
"Action": "AssumeRole",
"DurationSeconds": "3600",
"Format": "JSON",
"Policy": policy,
"RoleArn": "acs:ram::5081099437682835:role/ramtestossreadwrite",
"RoleSessionName": "<session_name>",
"SignatureMethod": "HMAC-SHA1",
"SignatureNonce": str(uuid.uuid1()),
"SignatureVersion": "1.0",
"Timestamp": datetime.strftime(datetime.utcnow(), "%Y-%m-%dT%H:%M:%SZ"),
"Version": "2015-04-01"
}
stringToSign = ""
for key in sorted(dictionaryParams.iterkeys()):
value = urllib.quote(dictionaryParams[key], safe="")
if stringToSign != "":
stringToSign += "&"
stringToSign += key + "=" + value
stringToSign = verb + "&%2F&" + urllib.quote(stringToSign)
signature = generateSignature(accessKeySecret + "&", stringToSign)
dictionaryParams["Signature"] = signature
params = urllib.urlencode(dictionaryParams)
path = "/?" + params
response = getHttpsRequest(host, verb, path)
if response.status == 200:
jsonData = json.loads(response.read())
print "Copy paste the respective information to file ossrest.py\n"
print "accessKeyId: " + jsonData['Credentials']['AccessKeyId']
print "accessKeySecret: " + jsonData['Credentials']['AccessKeySecret']
print "securityToken: " + jsonData['Credentials']['SecurityToken']
- ossrest.pyこれは、オブジェクトをアップロードして削除するコードです。
使用可能な機能は次のとおりです。
- 署名を生成する
- ヘッダーを生成する
- HTTP 要求を行う
- オブジェクトをアップロードする
- オブジェクトを削除する
ファイル “ossrest.py”のサンプルコードは次のとおりです。
from base64 import b64encode
from datetime import datetime
from Crypto.Hash import SHA, HMAC
import md5, httplib, urllib, uuid
##### MAIN CONFIG (STS)
accessKeyId = "<access_key_id>"
accessKeySecret = "<access_key_secret>"
securityToken = "<security_token>"
##### FUNCTION MANAGEMENT
def generateSignature(accessKeySecret, stringToSign):
hmac = HMAC.new(accessKeySecret, stringToSign, SHA)
return b64encode(hmac.digest())
def generateHeaders(verb, canonicalizedResource = "/", canonicalizedOSSHeaders = {}, signature = {}):
# authorization
stringToSign = verb + "\n"
if "content" in signature:
stringToSign += md5.new(signature["content"]).digest()
stringToSign += "\n"
if "content_type" in signature:
stringToSign += signature["content_type"]
stringToSign += "\n"
date = datetime.strftime(datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
stringToSign += date + "\n"
if len(canonicalizedOSSHeaders):
for index, value in canonicalizedOSSHeaders.items():
stringToSign += index.lower() + ":" + value + "\n"
stringToSign += canonicalizedResource
signature = generateSignature(accessKeySecret, stringToSign)
# headers
headers = {"Date": date, "Authorization": "OSS " + accessKeyId + ":" + signature}
headers.update(canonicalizedOSSHeaders)
return headers
def sendHttpsRequest(host, verb, headers, path = "/", params = ""):
conn = httplib.HTTPSConnection(host)
conn.request(verb, path, params, headers)
return conn.getresponse()
##### OBJECT MANAGEMENT
canonicalizedOSSHeaders = {"x-oss-acl": "public-read", "x-oss-security-token": securityToken}
bucketName = "<bucket_name>"
host = bucketName + ".oss-ap-southeast-1.aliyuncs.com"
hostMain = "oss-ap-southeast-1.aliyuncs.com"
folderName = "1"
fileName = "<filename>"
### UPLOAD OBJECT
verb = "PUT"
canonicalizedResource = "/" + bucketName + "/" + folderName + "/" + fileName
headers = generateHeaders(verb, canonicalizedResource, canonicalizedOSSHeaders)
response = sendHttpsRequest(host, verb, headers, "/" + folderName + "/" + fileName, open(fileName, "rb"))
print "Successfully uploaded " + fileName + " object to " + bucketName + "/" + folderName + " bucket/folder."
print response.status, response.reason
print response.read()
### DELETE OBJECT
verb = "DELETE"
canonicalizedResource = "/" + bucketName + "/" + folderName + "/" + fileName
headers = generateHeaders(verb, canonicalizedResource, canonicalizedOSSHeaders)
response = sendHttpsRequest(host, verb, headers, "/" + folderName + "/" + fileName)
print "Successfully deleted " + fileName + " object."
print response.status, response.reason
print response.read()
- other_sample.pyこれは他のシナリオのコードです。これらのサンプルは、STS に直接適用することはできませんが、例として提供されています。
使用可能な機能は次のとおりです。
- バケットを作成する
- リストバケット
- オブジェクトをアップロードする
- リストオブジェクト
- オブジェクトを削除する
- バケットを削除する
ファイル “other_sample.py”のサンプルコードは次のとおりです。
bucketName = "<bucket_name>"
host = bucketName + ".oss-ap-southeast-1.aliyuncs.com"
fileName = "<file_name>"
### CREATE BUCKET
verb = "PUT"
signature = {}
canonicalizedResource = "/" + bucketName + "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully created " + bucketName + " bucket."
print response.status, response.reason
print response.read()
### LIST BUCKET
host = "oss-ap-southeast-1.aliyuncs.com"
verb = "GET"
signature = {}
canonicalizedResource = "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully listed buckets."
print response.status, response.reason
print response.read()
### UPLOAD OBJECT
verb = "PUT"
signature = {}
canonicalizedResource = "/" + bucketName + "/" + fileName
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers, "/" + fileName, open(fileName, "rb"))
print "Successfully uploaded " + fileName + " object to " + bucketName + " bucket."
print response.status, response.reason
print response.read()
### LIST OBJECT
verb = "GET"
signature = {}
canonicalizedResource = "/" + bucketName + "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully listed objects in " + bucketName + " bucket."
print response.status, response.reason
print response.read()
### DELETE OBJECT
verb = "DELETE"
signature = {}
canonicalizedResource = "/" + bucketName + "/" + fileName
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers, "/" + fileName)
print "Successfully deleted " + fileName + " object."
print response.status, response.reason
print response.read()
### DELETE BUCKET
verb = "DELETE"
signature = {}
canonicalizedResource = "/" + bucketName + "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully deleted " + bucketName + " bucket."
print response.status, response.reason
print response.read()
期待される応答は次のとおりです。
- sts.py
- ossrest.py
結論
この例では OSS に焦点を当てていますが、STS サービスを使用して他の Alibaba Cloud サービスへのアクセスを制御することもできます。このチュートリアルで説明するユースケースは、ゲームです。OSS への短期アクセスを必要とするその他のシナリオやサービスには、以下が含まれます。
- Web アプリケーション
- モバイルアプリケーション