用戶聲明在已驗證訪問中通過和簽名驗證 - AWS 驗證存取

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

用戶聲明在已驗證訪問中通過和簽名驗證

之後 AWS Verified Access 實例成功驗證用戶,它將從 IdP 接收的用戶聲明發送到已驗證的訪問端點。使用者宣告已簽署,以便應用程式可以驗證簽章,並驗證宣告是由「已驗證存取」傳送的。在此過程中,會新增下列HTTP標頭:

x-amzn-ava-user-context

此標頭包含 JSON Web 令牌(JWT)格式的用戶聲明。該JWT格式包括 URL base64 編碼的標頭,有效負載和簽名。驗證訪問使用ES384(使用 SHA -384 哈希算法的ECDSA簽名算法)來生成簽名JWT。

應用程式可以將這些宣告用於個人化或其他使用者特定體驗。應用程式開發人員在使用前,應對身分提供者提供的每個聲明的唯一性等級和驗證進行自我教育。通常,sub聲明是識別給定用戶的最佳方法。

範例:JWT針對OIDC使用者宣告簽署

以下示例演示了用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身JWT分識別中心使用者宣告

下列範例示範 I IAM dentity Center 使用者宣告的標頭和承載在JWT格式中的外觀。

注意

對於IAM身分識別中心,宣告中只會包含使用者資訊。

示例標題:

{ "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 } } }

公有金鑰

由於已驗證存取執行個體不會加密使用者宣告,因此建議您設定要使用的已驗證存取端點HTTPS。如果您設定要使用的已驗證存取端點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'])