

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

# 範例 4：使用 RBAC 和 ABAC 進行多租戶存取控制
<a name="avp-mt-abac-rbac-examples"></a>

若要增強上一節中的 RBAC 範例，您可以將屬性新增至使用者，為多租戶存取控制建立 RBAC-ABAC 混合方法。此範例包含上一個範例中的相同角色，但會新增使用者屬性`account_lockout_flag`和內容參數 `uses_mfa`。此範例也會採用不同的方法來使用 RBAC 和 ABAC 實作多租用戶存取控制，並為每個租用戶使用一個共用政策存放區，而不是不同的政策存放區。

![具有 RBAC、ABAC、Amazon Verified Permissions 和 Cedar 的多租戶存取控制範例](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-api-access-authorization/images/avp-example-4.png)


此範例代表多租用戶 SaaS 解決方案，您需要提供租用戶 A 和租用戶 B 的授權決策，類似於先前的範例。

若要實作使用者鎖定功能，範例會將 屬性新增至授權請求中的`account_lockout_flag``User`實體主體。此旗標會鎖定使用者對系統的存取，並將鎖定使用者`DENY`的所有權限。`account_lockout_flag` 屬性與`User`實體相關聯，並對 有效，`User`直到跨多個工作階段主動撤銷旗標。此範例使用 `when`條件來評估 `account_lockout_flag`。

此範例也會新增請求和工作階段的詳細資訊。內容資訊指定已使用多重要素驗證來驗證工作階段。為了實作此驗證，範例會使用 `when`條件來評估 `uses_mfa`旗標做為內容欄位的一部分。如需新增內容的最佳實務的詳細資訊，請參閱 [Cedar 文件](https://docs.cedarpolicy.com/auth/entities-syntax.html)。

```
permit (
    principal in MultitenantApp::Role::"allAccessRole",
    action in [
        MultitenantApp::Action::"viewData",
        MultitenantApp::Action::"updateData"
    ],
    resource
)
when {
    principal.account_lockout_flag == false &&
    context.uses_mfa == true &&
    resource in principal.Tenant
};
```

此政策可防止存取 資源，除非資源與請求主體的 `Tenant` 屬性位於相同的群組中。這種維護租用戶隔離的方法稱為*單一共享多租用戶政策存放區*方法。如需多租用戶 SaaS 應用程式之 Verified Permissions 設計考量事項的詳細資訊，請參閱 [Verified Permissions 多租用戶設計考量](avp-design-considerations.md)事項一節。

此政策也會確保委託人是 的成員`allAccessRole`，並將動作限制為 `viewData`和 `updateData`。此外，此政策會驗證 `account_lockout_flag`是 ，`false`且 的內容值會`uses_mfa`評估為 `true`。

同樣地，以下政策可確保委託人和資源都與相同的租用戶相關聯，以防止跨租用戶存取。此政策也會確保委託人是 的成員，`viewDataRole`並將動作限制為 `viewData`。此外，它會驗證 `account_lockout_flag`是 ，`false`且 的內容值會`uses_mfa`評估為 `true`。

```
permit (
    principal in MultitenantApp::Role::"viewDataRole",
    action == MultitenantApp::Action::"viewData",
    resource
)
when {
    principal.account_lockout_flag == false &&
    context.uses_mfa == true &&
    resource in principal.Tenant
};
```

第三個政策類似於前一個政策。此政策要求資源成為 群組的成員，而該群組對應於由 表示的實體`principal.Tenant`。這可確保主體和資源都與租用戶 B 相關聯，以防止跨租用戶存取。此政策可確保委託人是 的成員，`updateDataRole`並將動作限制為 `updateData`。此外，此政策會驗證 `account_lockout_flag`是 ，`false`且 的內容值會`uses_mfa`評估為 `true`。

```
permit (
    principal in MultitenantApp::Role::"updateDataRole",
    action == MultitenantApp::Action::"updateData",
    resource
)
when {
    principal.account_lockout_flag == false &&
    context.uses_mfa == true &&
    resource in principal.Tenant
};
```

本節稍早討論的三個政策會評估下列授權請求。在此授權請求中， 類型 `User`和 值為 的委託人會使用角色 `Alice`提出`updateData`請求`allAccessRole`。 `Alice`具有值為 `Tenant`的 屬性`Tenant::"TenantA"`。`Alice` 嘗試執行的動作是 ，`updateData,`其將套用到的資源`SampleData`類型為 `Data`。 `SampleData` 具有 `TenantA`做為父實體。

根據政策存放區中的第一個`<DATAMICROSERVICE_POLICYSTOREID>`政策， `Alice`可以對資源執行 `updateData`動作，假設符合政策 `when`子句中的條件。第一個條件需要 `principal.Tenant` 屬性才能評估為 `TenantA`。第二個條件需要主體的 屬性`account_lockout_flag`為 `false`。最終條件需要內容`uses_mfa`為 `true`。由於符合所有三個條件，請求會傳回 `ALLOW`決策。

```
{
  "policyStoreId": "DATAMICROSERVICE_POLICYSTORE",
  "principal": {
      "entityType": "MultitenantApp::User",
      "entityId": "Alice"
  },
  "action": {
      "actionType": "MultitenantApp::Action",
      "actionId": "updateData"
  },
  "resource": {
      "entityType": "MultitenantApp::Data",
      "entityId": "SampleData"
  },
  "context": {
    "contextMap": {
        "uses_mfa": {
            "boolean": true
        }
    }
  },
  "entities": {
    "entityList": [
      {
        "identifier": {
            "entityType": "MultitenantApp::User",
            "entityId": "Alice"
        },
        "attributes": {
            {
                "account_lockout_flag": {
                    "boolean": false
                },
                "Tenant": {
                   "entityIdentifier": {
                        "entityType":"MultitenantApp::Tenant",
                        "entityId":"TenantA"
                   }
                }
            }
        },
        "parents": [
            {
                "entityType": "MultitenantApp::Role",
                "entityId": "allAccessRole"
            }
        ]
        },
     {
        "identifier": {
            "entityType": "MultitenantApp::Data",
            "entityId": "SampleData"
        },
        "attributes": {},
        "parents": [
            {
                "entityType": "MultitenantApp::Tenant",
                "entityId": "TenantA"
            }
        ]
      }
    ]
  }
}
```