

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

# 範例 1：具有 OPA 和 Rego 的基本 ABAC
<a name="opa-abac-examples"></a>

本節說明使用 OPA 對哪些使用者允許存取虛構薪資微服務中的資訊進行存取決策的情況。提供 Rego 程式碼片段，示範如何使用 Rego 來呈現存取控制決策。這些範例既不會詳盡，也不會完整探索 Rego 和 OPA 功能。如需 Rego 的更完整概觀，建議您參閱 OPA 網站上的 [Rego 文件](https://www.openpolicyagent.org/docs/latest/#rego)。

![具有 OPA 和 Rego 的基本 ABAC](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-api-access-authorization/images/opa-example-1.png)


## 基本 OPA 規則範例
<a name="basic-rules"></a>

在上圖中，OPA 針對薪資微服務強制執行的其中一個存取控制規則為：

*員工可以讀取自己的薪資。*

如果 Bob 嘗試存取薪資微服務以查看自己的薪資，薪資微服務可以將 API 呼叫重新導向至 OPA RESTful API 以做出存取決策。薪資服務會使用下列 JSON 輸入來查詢 OPA 是否有決策：

```
{
    "user": "bob",
    "method": "GET",
    "path": ["getSalary", "bob"]
}
```

OPA 會根據查詢選取政策。在此情況下，以下以 Rego 撰寫的政策會評估 JSON 輸入。

```
default allow = false
allow = true {
    input.method == "GET"
    input.path = ["getSalary", user]
    input.user == user
}
```

此政策預設拒絕存取。然後，它會將查詢繫結至全域變數 來評估查詢中的輸入`input`。點運算子會與此變數搭配使用，以存取變數的值。如果規則中的表達式也是 true，則 Rego 規則會`allow`傳回 true。Rego 規則會驗證輸入`method` 中的 是否等於 GET。然後，它會驗證清單中的第一個元素`path` 是在將清單中的第二個元素指派給變數 `getSalary`之前`user`。最後，它會檢查要存取的路徑是否`/getSalary/bob` 與`user`提出請求 `input.user`符合`user`變數。規則`allow`套用 if-then 邏輯以傳回布林值，如輸出所示：

```
{
    "allow": true
}
```

## 使用外部資料的部分規則
<a name="partial-rules"></a>

若要示範其他 OPA 功能，您可以將需求新增至您強制執行的存取規則。假設您想要在上圖的內容中強制執行此存取控制要求： 

*員工可以讀取向他們報告的任何人員的薪資。*

在此範例中，OPA 可存取可匯入的外部資料，以協助做出存取決策：

```
"managers": {
        "bob": ["dave", "john"],
        "carol": ["alice"]
}
```

 您可以在 OPA 中建立部分規則來產生任意 JSON 回應，這會傳回一組值，而不是固定的回應。這是部分規則的範例：

```
direct_report[user_ids] {
    user_ids = data.managers[input.user][_]
}
```

 此規則會傳回一組回報為 值的所有使用者`input.user`，在此情況下，該值為 `bob`。規則中的 `[_]` 建構用於反覆運算集合的值。這是規則的輸出：

```
{
    "direct_report": [
      "dave",
      "john"
    ]
}
```

擷取此資訊有助於判斷使用者是否為經理的直屬員工。對於某些應用程式，傳回動態 JSON 優於傳回簡單的布林值回應。

## 整合練習
<a name="abac-combination"></a>

最後一個存取需求比前兩個更複雜，因為它結合了這兩個需求中指定的條件：

*員工可以讀取自己的薪資以及向其報告的任何人的薪資。*

若要滿足此要求，您可以使用此 Rego 政策：

```
default allow = false
 
allow = true {
    input.method == "GET"
    input.path = ["getSalary", user]
    input.user == user
}
 
allow = true {
    input.method == "GET"
    input.path = ["getSalary", user]
    managers := data.managers[input.user][_]
    contains(managers, user)
}
```

政策中的第一個規則允許任何嘗試查看自己薪資資訊的使用者存取 ，如前所述。在 Rego 中具有兩個名稱相同的規則，即 `allow`做為邏輯**或**運算子。第二個規則會擷取與 相關聯的所有直接報告清單 `input.user`（來自上圖中的資料），並將此清單指派給`managers`變數。最後，規則會驗證其名稱是否包含在`managers`變數中，`input.user`藉此檢查嘗試查看其薪資的使用者是否為 的直屬報告。

本節中的範例非常基本，不提供完整或徹底探索 Rego 和 OPA 的功能。如需詳細資訊，請檢閱 [OPA 文件](https://www.openpolicyagent.org/docs/latest/)，請參閱 [OPA GitHub README](https://github.com/open-policy-agent/opa) 檔案，然後在 [Rego 遊樂場](https://play.openpolicyagent.org/)中實驗。