edit-icon download-icon

モバイルゲーム-セキュリティトークンサービスと Object Storage Service

最終更新日: Jun 11, 2018

はじめに

モバイルゲームでは、多くのアプリケーションで、開発者はプレーヤーのリソースを分離する必要があります。これには、ファイルの保存からユーザープロファイル情報の処理までさまざまなものが含まれます。従来の方法を使用することで、開発者はこの分離を管理できますが、セキュリティ、スケーラビリティ、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 はより柔軟性があります。

アーキテクチャー


1

この図では、RAM ユーザーは、OSS バケット内の別のフォルダにイメージをアップロードする必要があります。
アップロードプロセスは次のとおりです。

  1. ユーザは、AssumeRole を呼び出すことによって、Alibaba Cloud 内の特定のフォルダに対する OSS アクセスの読み取りおよび書き込みのRAM ロールを想定します。

  2. STS は、一連の一時的なセキュリティ資格情報を返します。

  3. ユーザーは一時的なセキュリティ資格情報を適用して OSS にアクセスします。その後、ユーザーはオブジェクトに対して読み取りまたは書き込み呼び出しを行うことができます。

ここでは例として OSS を取り上げます。ただし、STS は、Alibaba Cloud サービスの広い範囲に一時的にアクセスするために使用できます。このチュートリアルでは、細かいSTSパーミッションを使用して、特定の OSS バケットへのアクセスを制限しています。

実装

サンプルコードの 3 つのファイルは次のとおりです。

  • sts.py
    これは、ロールを想定し、accessKeyId、accessKeySecret、および securityToken などの重要な情報を取得するためのコードです。

使用可能な機能は次のとおりです。

  • リクエスト信頼性を保証するための署名を生成する
  • HTTPS リクエストを取得する

ファイル “sts.py”のサンプルコードは次のとおりです。

  1. from base64 import b64encode
  2. from datetime import datetime
  3. from Crypto.Hash import SHA, HMAC
  4. import md5, httplib, urllib, uuid, json
  5. ##### CONFIG MANAGEMENT
  6. accessKeyId = "<access_key_id>"
  7. accessKeySecret = "<access_key_secret>"
  8. ##### FUNCTION MANAGEMENT
  9. def generateSignature(accessKeySecret, stringToSign):
  10. hmac = HMAC.new(accessKeySecret, stringToSign, SHA)
  11. return b64encode(hmac.digest())
  12. def getHttpsRequest(host, verb, path):
  13. conn = httplib.HTTPSConnection(host)
  14. conn.request(verb, path)
  15. return conn.getresponse()
  16. # ###### STS MANAGEMENT
  17. host = "sts.aliyuncs.com"
  18. verb = "GET"
  19. bucketName = "<bucket_name>"
  20. folderName = "1"
  21. policy = '{"Statement": [{"Effect": "Allow","Action": ["oss:*"],"Resource": ["acs:oss:*:*:' + bucketName + '/' + folderName + '","acs:oss:*:*:' + bucketName + '/' + folderName + '/*"]}],"Version": "1"}'
  22. dictionaryParams = {
  23. "AccessKeyId": accessKeyId,
  24. "Action": "AssumeRole",
  25. "DurationSeconds": "3600",
  26. "Format": "JSON",
  27. "Policy": policy,
  28. "RoleArn": "acs:ram::5081099437682835:role/ramtestossreadwrite",
  29. "RoleSessionName": "<session_name>",
  30. "SignatureMethod": "HMAC-SHA1",
  31. "SignatureNonce": str(uuid.uuid1()),
  32. "SignatureVersion": "1.0",
  33. "Timestamp": datetime.strftime(datetime.utcnow(), "%Y-%m-%dT%H:%M:%SZ"),
  34. "Version": "2015-04-01"
  35. }
  36. stringToSign = ""
  37. for key in sorted(dictionaryParams.iterkeys()):
  38. value = urllib.quote(dictionaryParams[key], safe="")
  39. if stringToSign != "":
  40. stringToSign += "&"
  41. stringToSign += key + "=" + value
  42. stringToSign = verb + "&%2F&" + urllib.quote(stringToSign)
  43. signature = generateSignature(accessKeySecret + "&", stringToSign)
  44. dictionaryParams["Signature"] = signature
  45. params = urllib.urlencode(dictionaryParams)
  46. path = "/?" + params
  47. response = getHttpsRequest(host, verb, path)
  48. if response.status == 200:
  49. jsonData = json.loads(response.read())
  50. print "Copy paste the respective information to file ossrest.py\n"
  51. print "accessKeyId: " + jsonData['Credentials']['AccessKeyId']
  52. print "accessKeySecret: " + jsonData['Credentials']['AccessKeySecret']
  53. print "securityToken: " + jsonData['Credentials']['SecurityToken']
  • ossrest.py
    これは、オブジェクトをアップロードして削除するコードです。

使用可能な機能は次のとおりです。

  • 署名を生成する
  • ヘッダーを生成する
  • HTTP 要求を行う
  • オブジェクトをアップロードする
  • オブジェクトを削除する

ファイル “ossrest.py”のサンプルコードは次のとおりです。

  1. from base64 import b64encode
  2. from datetime import datetime
  3. from Crypto.Hash import SHA, HMAC
  4. import md5, httplib, urllib, uuid
  5. ##### MAIN CONFIG (STS)
  6. accessKeyId = "<access_key_id>"
  7. accessKeySecret = "<access_key_secret>"
  8. securityToken = "<security_token>"
  9. ##### FUNCTION MANAGEMENT
  10. def generateSignature(accessKeySecret, stringToSign):
  11. hmac = HMAC.new(accessKeySecret, stringToSign, SHA)
  12. return b64encode(hmac.digest())
  13. def generateHeaders(verb, canonicalizedResource = "/", canonicalizedOSSHeaders = {}, signature = {}):
  14. # authorization
  15. stringToSign = verb + "\n"
  16. if "content" in signature:
  17. stringToSign += md5.new(signature["content"]).digest()
  18. stringToSign += "\n"
  19. if "content_type" in signature:
  20. stringToSign += signature["content_type"]
  21. stringToSign += "\n"
  22. date = datetime.strftime(datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
  23. stringToSign += date + "\n"
  24. if len(canonicalizedOSSHeaders):
  25. for index, value in canonicalizedOSSHeaders.items():
  26. stringToSign += index.lower() + ":" + value + "\n"
  27. stringToSign += canonicalizedResource
  28. signature = generateSignature(accessKeySecret, stringToSign)
  29. # headers
  30. headers = {"Date": date, "Authorization": "OSS " + accessKeyId + ":" + signature}
  31. headers.update(canonicalizedOSSHeaders)
  32. return headers
  33. def sendHttpsRequest(host, verb, headers, path = "/", params = ""):
  34. conn = httplib.HTTPSConnection(host)
  35. conn.request(verb, path, params, headers)
  36. return conn.getresponse()
  37. ##### OBJECT MANAGEMENT
  38. canonicalizedOSSHeaders = {"x-oss-acl": "public-read", "x-oss-security-token": securityToken}
  39. bucketName = "<bucket_name>"
  40. host = bucketName + ".oss-ap-southeast-1.aliyuncs.com"
  41. hostMain = "oss-ap-southeast-1.aliyuncs.com"
  42. folderName = "1"
  43. fileName = "<filename>"
  44. ### UPLOAD OBJECT
  45. verb = "PUT"
  46. canonicalizedResource = "/" + bucketName + "/" + folderName + "/" + fileName
  47. headers = generateHeaders(verb, canonicalizedResource, canonicalizedOSSHeaders)
  48. response = sendHttpsRequest(host, verb, headers, "/" + folderName + "/" + fileName, open(fileName, "rb"))
  49. print "Successfully uploaded " + fileName + " object to " + bucketName + "/" + folderName + " bucket/folder."
  50. print response.status, response.reason
  51. print response.read()
  52. ### DELETE OBJECT
  53. verb = "DELETE"
  54. canonicalizedResource = "/" + bucketName + "/" + folderName + "/" + fileName
  55. headers = generateHeaders(verb, canonicalizedResource, canonicalizedOSSHeaders)
  56. response = sendHttpsRequest(host, verb, headers, "/" + folderName + "/" + fileName)
  57. print "Successfully deleted " + fileName + " object."
  58. print response.status, response.reason
  59. print response.read()
  • other_sample.py
    これは他のシナリオのコードです。これらのサンプルは、STS に直接適用することはできませんが、例として提供されています。

使用可能な機能は次のとおりです。

  • バケットを作成する
  • リストバケット
  • オブジェクトをアップロードする
  • リストオブジェクト
  • オブジェクトを削除する
  • バケットを削除する

ファイル “other_sample.py”のサンプルコードは次のとおりです。

  1. bucketName = "<bucket_name>"
  2. host = bucketName + ".oss-ap-southeast-1.aliyuncs.com"
  3. fileName = "<file_name>"
  4. ### CREATE BUCKET
  5. verb = "PUT"
  6. signature = {}
  7. canonicalizedResource = "/" + bucketName + "/"
  8. headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
  9. response = sendRequest(host, verb, headers)
  10. print "Successfully created " + bucketName + " bucket."
  11. print response.status, response.reason
  12. print response.read()
  13. ### LIST BUCKET
  14. host = "oss-ap-southeast-1.aliyuncs.com"
  15. verb = "GET"
  16. signature = {}
  17. canonicalizedResource = "/"
  18. headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
  19. response = sendRequest(host, verb, headers)
  20. print "Successfully listed buckets."
  21. print response.status, response.reason
  22. print response.read()
  23. ### UPLOAD OBJECT
  24. verb = "PUT"
  25. signature = {}
  26. canonicalizedResource = "/" + bucketName + "/" + fileName
  27. headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
  28. response = sendRequest(host, verb, headers, "/" + fileName, open(fileName, "rb"))
  29. print "Successfully uploaded " + fileName + " object to " + bucketName + " bucket."
  30. print response.status, response.reason
  31. print response.read()
  32. ### LIST OBJECT
  33. verb = "GET"
  34. signature = {}
  35. canonicalizedResource = "/" + bucketName + "/"
  36. headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
  37. response = sendRequest(host, verb, headers)
  38. print "Successfully listed objects in " + bucketName + " bucket."
  39. print response.status, response.reason
  40. print response.read()
  41. ### DELETE OBJECT
  42. verb = "DELETE"
  43. signature = {}
  44. canonicalizedResource = "/" + bucketName + "/" + fileName
  45. headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
  46. response = sendRequest(host, verb, headers, "/" + fileName)
  47. print "Successfully deleted " + fileName + " object."
  48. print response.status, response.reason
  49. print response.read()
  50. ### DELETE BUCKET
  51. verb = "DELETE"
  52. signature = {}
  53. canonicalizedResource = "/" + bucketName + "/"
  54. headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
  55. response = sendRequest(host, verb, headers)
  56. print "Successfully deleted " + bucketName + " bucket."
  57. print response.status, response.reason
  58. print response.read()

期待される応答は次のとおりです。

  • sts.py
    2
  • ossrest.py
    3

結論

この例では OSS に焦点を当てていますが、STS サービスを使用して他の Alibaba Cloud サービスへのアクセスを制御することもできます。このチュートリアルで説明するユースケースは、ゲームです。OSS への短期アクセスを必要とするその他のシナリオやサービスには、以下が含まれます。

  • Web アプリケーション
  • モバイルアプリケーション

追加情報