

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

# Verified Access 中的使用者宣告傳遞和簽章驗證
<a name="user-claims-passing"></a>

 AWS Verified Access 執行個體成功驗證使用者後，會將從 IdP 收到的使用者宣告傳送至 Verified Access 端點。使用者宣告會經過簽署，讓應用程式可以驗證簽章，也可以驗證宣告是由 Verified Access 傳送。在此過程中，會新增下列 HTTP 標頭：

`x-amzn-ava-user-context`

此標頭包含 JSON Web 字符 (JWT) 格式的使用者宣告。JWT 格式包含使用 base64 URL 編碼的標頭、承載和簽章。Verified Access 使用 ES384 （使用 SHA-384 雜湊演算法的 ECDSA 簽章演算法） 來產生 JWT 簽章。

應用程式可以將這些宣告用於個人化或其他使用者特定的體驗。應用程式開發人員應在使用前，自行了解身分提供者所提供每個宣告的唯一性和驗證程度。一般而言，`sub`宣告是識別指定使用者的最佳方式。

**Topics**
+ [OIDC 使用者宣告的 JWT](#oidc-sample)
+ [IAM Identity Center 使用者宣告的 JWT](#IdC-sample)
+ [公有金鑰](#public-keys)
+ [擷取和解碼 JWT](#sample-code)

## 範例：OIDC 使用者宣告的已簽署 JWT
<a name="oidc-sample"></a>

下列範例示範 OIDC 使用者宣告的標頭和承載在 JWT 格式中會是什麼樣子。

範例標頭：

```
{
   "alg": "ES384",
   "kid": "12345678-1234-1234-1234-123456789012",
   "signer": "arn:aws:ec2:us-east-1:123456789012:verified-access-instance/vai-abc123xzy321a2b3c", 
   "iss": "OIDC Issuer URL",
   "exp": "expiration" (120 secs)
}
```

承載範例：

```
{
   "sub": "xyzsubject",
   "email": "xxx@amazon.com",
   "email_verified": true,
   "groups": [
      "Engineering",
      "finance"
   ],
   "additional_user_context": {
      "aud": "xxx",
      "exp": 1000000000,
      "groups": [
         "group-id-1",
         "group-id-2"
      ],
      "iat": 1000000000,
      "iss": "https://oidc-tp.com/",
      "sub": "xyzsubject",
      "ver": "1.0"
   }
}
```

## 範例：IAM Identity Center 使用者宣告的已簽署 JWT
<a name="IdC-sample"></a>

下列範例示範 IAM Identity Center 使用者宣告的標頭和承載在 JWT 格式中會是什麼樣子。

**注意**  
對於 IAM Identity Center，只有使用者資訊會包含在宣告中。

範例標頭：

```
{
   "alg": "ES384",
   "kid": "12345678-1234-1234-1234-123456789012",
   "signer": "arn:aws:ec2:us-east-1:123456789012:verified-access-instance/vai-abc123xzy321a2b3c", 
   "iss": "arn:aws:ec2:us-east-1:123456789012:verified-access-trust-provider/vatp-abc123xzy321a2b3c",
   "exp": "expiration" (120 secs)
}
```

承載範例：

```
{
    "user": {
        "user_id": "f478d4c8-a001-7064-6ea6-12423523",
        "user_name": "test-123",
        "email": {
            "address": "test@amazon.com",
            "verified": false
        }
    }
}
```

## 公有金鑰
<a name="public-keys"></a>

由於 Verified Access 執行個體不會加密使用者宣告，我們建議您將 Verified Access 端點設定為使用 HTTPS。如果您將 Verified Access 端點設定為使用 HTTP，請務必使用安全群組限制端點的流量。

為了確保安全性，您必須先驗證簽章，才能根據宣告執行任何授權，並驗證 JWT 標頭中的 `signer` 欄位是否包含預期的 Verified Access 執行個體 ARN。

若要取得公有金鑰，請從 JWT 標頭取得金鑰 ID，並用其在端點查閱公有金鑰。

每個 的端點 AWS 區域 如下：

`https://public-keys.prod.verified-access.<region>.amazonaws.com/<key-id>`

## 範例：擷取和解碼 JWT
<a name="sample-code"></a>

下列程式碼範例示範如何在 Python 3.9 中取得金鑰 ID、公有金鑰和承載。

```
import jwt
import requests
import base64
import json

# Step 1: Validate the signer
expected_verified_access_instance_arn = 'arn:aws:ec2:region-code:account-id:verified-access-instance/verified-access-instance-id'

encoded_jwt = headers.dict['x-amzn-ava-user-context']
jwt_headers = encoded_jwt.split('.')[0]
decoded_jwt_headers = base64.b64decode(jwt_headers)
decoded_jwt_headers = decoded_jwt_headers.decode("utf-8")
decoded_json = json.loads(decoded_jwt_headers)
received_verified_access_instance_arn = decoded_json['signer']

assert expected_verified_access_instance_arn == received_verified_access_instance_arn, "Invalid Signer"

# Step 2: Get the key id from JWT headers (the kid field)
kid = decoded_json['kid']

# Step 3: Get the public key from regional endpoint
url = 'https://public-keys.prod.verified-access.' + region + '.amazonaws.com/' + kid
req = requests.get(url)
pub_key = req.text

# Step 4: Get the payload
payload = jwt.decode(encoded_jwt, pub_key, algorithms=['ES384'])
```