本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Verified Access 中的使用者宣告傳遞和簽章驗證
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
宣告是識別指定使用者的最佳方式。
範例:OIDC 使用者宣告的已簽署 JWT
下列範例示範 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"
]
}
範例:IAM Identity Center 使用者宣告的已簽署 JWT
下列範例示範 JWT 格式的 IAM Identity Center 使用者宣告的標頭和承載會是什麼樣子。
注意
對於 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
}
}
}
公有金鑰
由於 Verified Access 執行個體不會加密使用者宣告,我們建議您設定 Verified Access 端點以使用 HTTPS。如果您將 Verified Access 端點設定為使用 HTTP,請務必使用安全群組限制端點的流量。
為了確保安全性,您必須先驗證簽章,才能根據宣告進行任何授權,並驗證 JWT 標頭中的 signer
欄位是否包含預期的已驗證存取執行個體 ARN。
若要取得公有金鑰,請從 JWT 標頭取得金鑰 ID,並用其在端點查閱公有金鑰。
每個 的端點 AWS 區域 如下:
https://public-keys.prod.verified-access.<region>.amazonaws.com/<key-id>
範例:擷取和解碼 JWT
下列程式碼範例示範如何在 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'])