

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 AWS Lambda 字符販賣機實作 Amazon S3 的 SaaS 租用戶隔離
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine"></a>

*Tabby Ward、Thomas Davis 和 Sravan Periyathambi，Amazon Web Services*

## 總結
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-summary"></a>

多租戶 SaaS 應用程式必須實作系統，以確保維持租戶隔離。當您將租戶資料存放在相同的 AWS 資源時，例如當多個租戶將資料存放在相同的 Amazon Simple Storage Service (Amazon S3) 儲存貯體時，您必須確保跨租戶存取不會發生。字符販賣機 (TVMs) 是提供租戶資料隔離的一種方式。這些機器提供一種機制來取得權杖，同時抽象化這些權杖產生方式的複雜性。開發人員可以使用 TVM，而無需詳細了解其如何產生字符。

此模式使用 實作 TVM AWS Lambda。TVM 會產生權杖，其中包含臨時安全權杖服務 (STS) 憑證，以限制對 S3 儲存貯體中單一 SaaS 租用戶資料的存取。

TVMs和此模式提供的程式碼通常用於衍生自 JSON Web Token (JWTs) 的宣告，以將 AWS 資源請求與租用戶範圍 AWS Identity and Access Management (IAM) 政策建立關聯。您可以使用此模式中的程式碼做為實作 SaaS 應用程式的基礎，該應用程式會根據 JWT 權杖中提供的宣告產生範圍廣泛的暫時 STS 憑證。

## 先決條件和限制
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-prereqs"></a>

**先決條件**
+ 作用中 AWS 帳戶。
+ AWS Command Line Interface (AWS CLI) [1.19.0 版或更新版本](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html)，在 macOS、Linux 或 Windows 上安裝和設定。或者，您可以使用 AWS CLI [2.1 版或更新版本。](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)

**限制**
+ 此程式碼在 Java 中執行，目前不支援其他程式設計語言。 
+ 範例應用程式不包含 AWS 跨區域或災難復原 (DR) 支援。 
+ 此模式示範適用於 SaaS 應用程式的 Lambda TVM 如何提供範圍租用戶存取。此模式不適用於生產環境，如果在特定應用程式或使用案例中沒有額外的安全測試。

## Architecture
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-architecture"></a>

**目標技術堆疊**
+ AWS Lambda
+ Amazon S3
+ IAM
+ AWS Security Token Service (AWS STS)

**目標架構**

![\[產生權杖以取得臨時 STS 登入資料，以存取 S3 儲存貯體中的資料。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/97a34c8e-d04e-40b6-acbf-1baa176d22a9/images/14d0508a-703b-4229-85e6-c5094de7fe01.png)


 

## 工具
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-tools"></a>

**AWS 服務**
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是一種開放原始碼工具，可協助您 AWS 服務 透過命令列 shell 中的命令與 互動。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 透過控制已驗證並獲授權使用的人員，協助您安全地管理對 AWS 資源的存取。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一項運算服務，可協助您執行程式碼，無需佈建或管理伺服器。它只會在需要時執行程式碼並自動擴展，因此您只需支付使用的運算時間。
+ [AWS Security Token Service (AWS STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) 可協助您為使用者請求暫時、有限權限的登入資料。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) 是一種雲端型物件儲存服務，可協助您儲存、保護和擷取任何數量的資料。

**Code**

此模式的原始碼可做為附件使用，並包含下列檔案：
+ `s3UploadSample.jar` 提供 Lambda 函數的原始碼，可將 JSON 文件上傳至 S3 儲存貯體。
+ `tvm-layer.zip` 提供可重複使用的 Java 程式庫，可為 Lambda 函數提供權杖 (STS 臨時登入資料），以存取 S3 儲存貯體並上傳 JSON 文件。
+ `token-vending-machine-sample-app.zip` 提供用來建立這些成品和編譯指示的原始碼。

若要使用這些檔案，請遵循下一節中的指示。

## 史詩
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-epics"></a>

### 判斷變數值
<a name="determine-variable-values"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 判斷變數值。 | 此模式的實作包含數個必須一致使用的變數名稱。決定應該用於每個變數的值，並在後續步驟中請求時提供該值。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine.html) | 雲端管理員 | 

### 建立 S3 儲存貯體
<a name="create-an-s3-bucket"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 為範例應用程式建立 S3 儲存貯體。 | 使用下列 AWS CLI 命令來建立 S3 儲存貯體。在程式碼片段中提供 `<sample-app-bucket-name>`****值：<pre>aws s3api create-bucket --bucket <sample-app-bucket-name></pre>Lambda 範例應用程式會將 JSON 檔案上傳至此儲存貯體。 | 雲端管理員 | 

### 建立 IAM TVM 角色和政策
<a name="create-the-iam-tvm-role-and-policy"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立 TVM 角色。 | 使用下列其中一個 AWS CLI 命令來建立 IAM 角色。在 命令中提供 `<sample-tvm-role-name>`****值。對於 macOSor Linux shell：<pre>aws iam create-role \<br />--role-name <sample-tvm-role-name> \<br />--assume-role-policy-document '{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />            "Effect": "Allow",<br />            "Action": [<br />                "sts:AssumeRole"<br />            ],<br />            "Principal": {<br />                "Service": [<br />                    "lambda.amazonaws.com"<br />                ]<br />            },<br />            "Condition": {<br />                "StringEquals": {<br />                    "aws:SourceAccount": "<AWS Account ID>"<br />                }<br />            }<br />        }<br />    ]<br />}'</pre>對於 Windows 命令列：<pre>aws iam create-role ^<br />--role-name <sample-tvm-role-name> ^<br />--assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"sts:AssumeRole\"], \"Principal\": {\"Service\": [\"lambda.amazonaws.com\"]}, \"Condition\": {\"StringEquals\": {\"aws:SourceAccount\": \"<AWS Account ID>\"}}}]}"</pre>Lambda 範例應用程式會在叫用應用程式時擔任此角色。使用範圍政策擔任應用程式角色的功能為程式碼提供更廣泛存取 S3 儲存貯體的許可。 | 雲端管理員 | 
| 建立內嵌 TVM 角色政策。 | 使用下列其中一個 AWS CLI 命令來建立 IAM 政策。在命令中提供 `<sample-tvm-role-name>`****`<AWS Account ID>`、 和 `<sample-app-role-name>`值。對於 macOS 或 Linux shell：<pre>aws iam put-role-policy \<br />--role-name <sample-tvm-role-name> \<br />--policy-name assume-app-role \<br />--policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": "Allow", <br />            "Action": "sts:AssumeRole", <br />            "Resource": "arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>"<br />        }<br />    ]}'</pre>對於 Windows 命令列：<pre>aws iam put-role-policy ^<br />--role-name <sample-tvm-role-name> ^<br />--policy-name assume-app-role ^<br />--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": \"sts:AssumeRole\", \"Resource\": \"arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>\"}]}"</pre>此政策會連接到 TVM 角色。它為程式碼提供擔任應用程式角色的能力，其具有更廣泛存取 S3 儲存貯體的許可。 | 雲端管理員 | 
| 連接 受管 Lambda 政策。 | 使用下列 AWS CLI 命令來連接`AWSLambdaBasicExecutionRole` IAM 政策。在 命令中提供 `<sample-tvm-role-name>`值：<pre>aws iam attach-role-policy \<br />--role-name <sample-tvm-role-name> \<br />--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole</pre>對於 Windows 命令列：<pre>aws iam attach-role-policy ^<br />--role-name <sample-tvm-role-name> ^<br />--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole</pre>此受管政策會連接至 TVM 角色，以允許 Lambda 將日誌傳送至 Amazon CloudWatch。 | 雲端管理員 | 

### 建立 IAM 應用程式角色和政策
<a name="create-the-iam-application-role-and-policy"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立應用程式角色。 | 使用下列其中一個 AWS CLI 命令來建立 IAM 角色。在 命令中提供 `<AWS Account ID>`、 `<sample-app-role-name>`和 `<sample-tvm-role-name>`值。對於 macOS 或 Linux shell：<pre>aws iam create-role \<br />--role-name <sample-app-role-name> \<br />--assume-role-policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": <br />            "Allow",<br />            "Principal": {<br />                "AWS": "arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name>"<br />            },<br />            "Action": "sts:AssumeRole"<br />        }<br />    ]}'</pre>對於 Windows 命令列：<pre>aws iam create-role ^<br />--role-name <sample-app-role-name> ^<br />--assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name>\"},\"Action\": \"sts:AssumeRole\"}]}"</pre>Lambda 範例應用程式會使用範圍政策擔任此角色，以取得 S3 儲存貯體的租戶型存取權。 | 雲端管理員 | 
| 建立內嵌應用程式角色政策。 | 使用下列其中一個 AWS CLI mmands 來建立 IAM 政策。在 命令中提供 `<sample-app-role-name>`和 `<sample-app-bucket-name>`****值。對於 macOS 或 Linux shell：<pre>aws iam put-role-policy \<br />--role-name <sample-app-role-name> \<br />--policy-name s3-bucket-access \<br />--policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": "Allow", <br />            "Action": [<br />                "s3:PutObject", <br />                "s3:GetObject", <br />                "s3:DeleteObject"<br />            ], <br />            "Resource": "arn:aws:s3:::<sample-app-bucket-name>/*"<br />        }, <br />        {<br />            "Effect": "Allow", <br />            "Action": ["s3:ListBucket"], <br />            "Resource": "arn:aws:s3:::<sample-app-bucket-name>"<br />        }<br />    ]}'</pre>對於 Windows 命令列：<pre>aws iam put-role-policy ^<br />--role-name <sample-app-role-name> ^<br />--policy-name s3-bucket-access ^<br />--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:PutObject\", \"s3:GetObject\", \"s3:DeleteObject\"], \"Resource\": \"arn:aws:s3:::<sample-app-bucket-name>/*\"}, {\"Effect\": \"Allow\", \"Action\": [\"s3:ListBucket\"], \"Resource\": \"arn:aws:s3:::<sample-app-bucket-name>\"}]}"</pre>此政策會連接至應用程式角色。它提供對 S3 儲存貯體中物件的廣泛存取。當範例應用程式擔任角色時，這些許可的範圍會限定為具有 TVM 動態產生政策的特定租用戶。 | 雲端管理員 | 

### 使用 TVM 建立 Lambda 範例應用程式
<a name="create-the-lam-sample-application-with-tvm"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 下載編譯的來源檔案。 | 下載 `s3UploadSample.jar`和 `tvm-layer.zip`****檔案，其中包含為附件。中提供了用於建立這些成品和編譯函數的原始程式碼`token-vending-machine-sample-app.zip`。 | 雲端管理員 | 
| 建立 Lambda 層。 | 使用下列 AWS CLI 命令來建立 Lambda 層，讓 Lambda 可存取 TVM。 如果您不是從下載的位置執行此命令` tvm-layer.zip`，請在 `--zip-file`參數`tvm-layer.zip`中提供正確的路徑。 <pre>aws lambda publish-layer-version \<br />--layer-name sample-token-vending-machine \<br />--compatible-runtimes java11 \<br />--zip-file fileb://tvm-layer.zip</pre>對於 Windows 命令列：<pre>aws lambda publish-layer-version ^<br />--layer-name sample-token-vending-machine ^<br />--compatible-runtimes java11 ^<br />--zip-file fileb://tvm-layer.zip</pre>此命令會建立包含可重複使用 TVM 程式庫的 Lambda 層。 | 雲端管理員、應用程式開發人員 | 
| 建立 Lambda 函數。 | 使用下列 AWS CLI 命令來建立 Lambda 函數。在命令中提供 `<sample-app-function-name>`、`<AWS Account ID>`、`<sample-app-bucket-name>`、、 `<AWS Region>` `<sample-tvm-role-name>`和 `<sample-app-role-name>`值。 如果您不是從下載 的位置執行此命令`s3UploadSample.jar`，請在 `--zip-file`參數`s3UploadSample.jar`中提供正確的路徑。 <pre>aws lambda create-function \<br />--function-name <sample-app-function-name>  \<br />--timeout 30 \<br />--memory-size 256 \<br />--runtime java11 \<br />--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> \<br />--handler com.amazon.aws.s3UploadSample.App \<br />--zip-file fileb://s3UploadSample.jar \<br />--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 \<br />--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,<br />ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"</pre>對於 Windows 命令列：<pre>aws lambda create-function ^<br />--function-name <sample-app-function-name>  ^<br />--timeout 30 ^<br />--memory-size 256 ^<br />--runtime java11 ^<br />--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> ^<br />--handler com.amazon.aws.s3UploadSample.App ^<br />--zip-file fileb://s3UploadSample.jar ^<br />--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 ^<br />--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"</pre>此命令會建立連接範例應用程式程式碼和 TVM layer 的 Lambda 函數。它也會設定兩個環境變數： `S3_BUCKET`和 `ROLE`。範例應用程式使用這些變數來決定要擔任的角色，以及要上傳 JSON 文件的 S3 儲存貯體。 | 雲端管理員、應用程式開發人員 | 

### 測試範例應用程式和 TVM
<a name="test-the-sample-application-and-tvm"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 叫用 Lambda 範例應用程式。 | 使用下列其中一個 AWS CLI 命令，以其預期的承載啟動 Lambda 範例應用程式。在 命令中提供 `<sample-app-function-name>`和 `<sample-tenant-name>`值。對於 macOS 和 Linux shell：<pre>aws lambda invoke \<br />--function <sample-app-function-name> \<br />--invocation-type RequestResponse \<br />--payload '{"tenant": "<sample-tenant-name>"}' \<br />--cli-binary-format raw-in-base64-out response.json</pre>對於 Windows 命令列：<pre>aws lambda invoke ^<br />--function <sample-app-function-name> ^<br />--invocation-type RequestResponse ^<br />--payload "{\"tenant\": \"<sample-tenant-name>\"}" ^<br />--cli-binary-format raw-in-base64-out response.json</pre>此命令會呼叫 Lambda 函數，並在`response.json`文件中傳回結果。在許多以 Unix 為基礎的系統上，您可以將 `response.json` 變更為 `/dev/stdout`，直接將結果輸出到您的 shell，而無需建立另一個檔案。 變更此 Lambda 函數後續調用中的`<sample-tenant-name>`值會變更 JSON 文件的位置，以及字符提供的許可。 | 雲端管理員、應用程式開發人員 | 
| 檢視 S3 儲存貯體以查看建立的物件。 | 瀏覽至您先前建立的 S3 儲存貯體 (`<sample-app-bucket-name>`)。此儲存貯體包含值為 的 S3 物件字首`<sample-tenant-name>`。在此字首下，您會找到名為 且具有 UUID 的 JSON 文件。多次叫用範例應用程式會新增更多 JSON 文件。 | 雲端管理員 | 
| 在 CloudWatch Logs 中檢視範例應用程式的日誌。 | 檢視與 CloudWatch Logs `<sample-app-function-name>`中名為 的 Lambda 函數相關聯的日誌。如需說明，請參閱 [Lambda 文件中的將 Lambda 函數日誌傳送至 CloudWatch Logs](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html)。您可以在這些日誌中檢視 TVM 產生的租戶範圍政策。此租用戶範圍政策將範例應用程式的許可授予 Amazon S3 **PutObject**、**GetObject**、**DeleteObject** 和 **ListBucket** APIs，但僅適用於與 相關聯的物件字首`<sample-tenant-name>`。在範例應用程式的後續調用中，如果您變更 `<sample-tenant-name>`，TVM 會更新範圍政策，以對應調用承載中提供的租用戶。此動態產生的政策顯示如何在 SaaS 應用程式中使用 TVM 維護租戶範圍存取。 TVM 功能是在 Lambda 層中提供，因此可以連接到應用程式使用的其他 Lambda 函數，而不必複寫程式碼。如需動態產生政策的圖例，請參閱[其他資訊](#implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-additional)一節。 | 雲端管理員 | 

## 相關資源
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-resources"></a>
+ [使用動態產生的 IAM 政策隔離租用戶](https://aws.amazon.com/blogs/apn/isolating-saas-tenants-with-dynamically-generated-iam-policies/) （部落格文章）
+ [在 SaaS 環境中套用動態產生的隔離政策 ](https://aws.amazon.com/blogs/apn/applying-dynamically-generated-isolation-policies-in-saas-environments/)（部落格文章）
+ [上的 SaaS AWS](https://aws.amazon.com/saas/)

## 其他資訊
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-additional"></a>

以下日誌顯示此模式中 TVM 程式碼產生的動態產生政策。在此螢幕擷取畫面中， `<sample-app-bucket-name>`是`DOC-EXAMPLE-BUCKET` ，而 `<sample-tenant-name>`是 `test-tenant-1`。此範圍政策傳回的 STS 登入資料無法在 S3 儲存貯體中的物件上執行任何動作，但與物件金鑰字首 相關聯的物件除外`test-tenant-1`。

![\[日誌顯示由 TVM 程式碼產生的動態產生政策。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/97a34c8e-d04e-40b6-acbf-1baa176d22a9/images/d4776ebe-fb8f-41ac-b8c5-b4f97a821c8c.png)


## 附件
<a name="attachments-97a34c8e-d04e-40b6-acbf-1baa176d22a9"></a>

若要存取與本文件相關聯的其他內容，請解壓縮下列檔案： [attachment.zip](samples/p-attach/97a34c8e-d04e-40b6-acbf-1baa176d22a9/attachments/attachment.zip)