

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

# 透過 MFA 實現安全的 API 存取
<a name="id_credentials_mfa_configure-api-require"></a>

利用 IAM 政策，可以指定允許使用者呼叫的 API 操作。您可以套用額外安全性，方法是先要求使用者透過多重要素驗證 (MFA) 進行身分驗證，然後再允許使用者執行特別敏感的動作。

例如，您可能擁有允許使用者執行 Amazon EC2 `RunInstances`、`DescribeInstances` 與 `StopInstances` 動作的政策。但您可能想要限制類似 的破壞性動作，`TerminateInstances`並確保使用者只有在使用 AWS MFA 裝置進行身分驗證時，才能執行該動作。

**Topics**
+ [概觀](#MFAProtectedAPI-overview)
+ [使用案例：跨帳戶委派的 MFA 防護](#MFAProtectedAPI-cross-account-delegation)
+ [使用案例：目前帳戶中 API 操作存取的 MFA 防護](#MFAProtectedAPI-user-mfa)
+ [使用案例：擁有以資源為基礎的政策之資源的 MFA 防護](#MFAProtectedAPI-resource-policies)

## 概觀
<a name="MFAProtectedAPI-overview"></a>

新增 MFA 防護到 API 操作將包括以下任務：

1. 管理員會為每個必須提出需要 AWS MFA 身分驗證之 API 請求的使用者設定 MFA 裝置。如需詳細資訊，請參閱[AWS IAM 中的多重要素驗證](id_credentials_mfa.md)。

1. 管理員會為使用者建立政策，其中包含檢查使用者是否使用 AWS MFA 裝置進行身分驗證的 `Condition` 元素。

1. 使用者呼叫其中一個支援 MFA 參數的 AWS STS API 操作：[AssumeRole](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) 或 [GetSessionToken](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html)。作為呼叫的一部分，使用者包含與其關聯的裝置的裝置識別碼。使用者也包含裝置產生之以時間為基礎的單次密碼 (TOTP)。在任一情況下，使用者都會取回稍後用來向 AWS發出其他請求的臨時安全憑證。
**注意**  
只有在服務支援臨時安全憑證時，才可使用該服務的 API 操作的 MFA 防護。如需這些服務的清單，請參閱[使用暫時安全憑證存取 AWS](https://docs.aws.amazon.com/STS/latest/UsingSTS/UsingTokens.html)。

如果授權失敗， 會 AWS 傳回存取遭拒錯誤訊息 （如同任何未經授權的存取）。使用受 MFA 保護的 API 政策時，如果使用者嘗試在沒有有效 MFA 身分驗證的情況下呼叫 API 操作， 會 AWS 拒絕存取政策中指定的 API 操作。如果 API 操作請求的時間戳記在政策中指定的允許範圍之外，也會拒絕該操作。使用者必須使用 MFA 代碼和裝置序號來請求新的臨時安全性憑證，並透過 MFA 重新進行身分驗證。

### 含有 MFA 條件的 IAM 政策
<a name="MFAProtectedAPI-policies"></a>

含有 MFA 條件的政策可連接到以下項目：
+ IAM 使用者或群組
+ 資源，例如 Amazon S3 儲存貯體、Amazon SQS 佇列或者 Amazon SNS 主題
+ 可由使用者擔任的 IAM 角色的信任政策

可使用政策中的 MFA 條件來檢查以下屬性：
+ 存在 - 如果只是驗證使用者是否已使用 MFA 進行身分驗證，請檢查 `aws:MultiFactorAuthPresent` 金鑰在 `Bool` 條件中是否為 `True`。只有在使用者使用短期憑證進行驗證時，索引鍵才會存在。長期憑證，例如存取金鑰，則不包括此鍵。
+ 持續時間 - 如果您只希望在 MFA 身分驗證後的指定時間內授予存取權限，請使用數值條件類型將 `aws:MultiFactorAuthAge` 索引鍵的有效期與某個值 (如 3600 秒) 進行比較。請注意，如果未使用 MFA，則 `aws:MultiFactorAuthAge` 索引鍵不會顯示。

以下範例顯示 IAM 角色的信任政策，該政策包含一個 MFA 條件，用於測試是否存在 MFA 身分驗證。使用此政策，來自 `Principal`元素中 AWS 帳戶 指定 (`ACCOUNT-B-ID`以有效的 AWS 帳戶 ID 取代） 的使用者可以擔任此政策所連接的角色。不過，如果使用者使用 MFA 進行身分驗證，這類的使用者只能擔任該角色。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": {
    "Effect": "Allow",
    "Principal": {"AWS": "ACCOUNT-B-ID"},
    "Action": "sts:AssumeRole",
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }
}
```

------

如需有關 MFA 條件類型的詳細資訊，請參閱[AWS 全域條件內容索引鍵](reference_policies_condition-keys.md)、[數位條件運算子](reference_policies_elements_condition_operators.md#Conditions_Numeric) 與 [用於檢查條件索引鍵是否存在的條件運算子](reference_policies_elements_condition_operators.md#Conditions_Null)。

### 在 GetSessionToken 和 AssumeRole 之間選擇
<a name="scenarios"></a>

AWS STS 提供兩種 API 操作，可讓使用者傳遞 MFA 資訊： `GetSessionToken`和 `AssumeRole`。使用者呼叫以獲取臨時安全憑證的 API 操作取決於適用於以下哪個案例。

**針對以下案例使用 `GetSessionToken`：**
+ 呼叫 API 操作，以存取 AWS 帳戶 與發出請求的 IAM 使用者相同的 中的資源。請注意，*只有在*`GetSessionToken`憑證請求中包含 MFA 資訊時，請求中的臨時憑證才能存取 IAM 和 AWS STS API 操作。由於 `GetSessionToken` 傳回的臨時憑證包含 MFA 資訊，因此您可以檢查由該憑證發出的個別 API 操作中的 MFA。
+ 存取受到以資源為基礎且包含 MFA 條件的政策所保護的資源。

`GetSessionToken` 操作的目的是使用 MFA 驗證使用者的身分。您不能使用政策來控制驗證操作。

**針對以下案例使用 `AssumeRole`：**
+ 呼叫存取相同的或不同的 AWS 帳戶中的資源的 API 操作。API 呼叫可以包含任何 IAM 或 AWS STS API。請注意，要保護存取，您可以在使用者擔任角色時強制執行 MFA。由 `AssumeRole` 傳回的臨時憑證未將 MFA 資訊包含在上下文中，因此您無法檢查 MFA 的單一 API 操作。這就是您必須使用 `GetSessionToken` 限制對受到以資源為基礎之政策保護的資源的存取的原因。

**注意**  
AWS CloudTrail 當 IAM 使用者使用 MFA 登入時， 日誌將包含 MFA 資訊。如果 IAM 使用者擔任 IAM 角色，CloudTrail 也會將 `mfaAuthenticated: true` 記錄在使用該擔任角色執行的動作的 `sessionContext` 屬性中。不過，CloudTrail 記錄與使用擔任角色的憑證進行 API 呼叫時 IAM 所需的記錄是分開的。如需詳細資訊，請參閱 [CloudTrail userIdentity 元素](https://docs.aws.amazon.com//awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html)。

本文件稍後將提供有關如何實施這些使用案例的詳細資訊。

### 有關受 MFA 保護的 API 存取的要點
<a name="MFAProtectedAPI-important-points"></a>

瞭解 API 操作的 MFA 防護有下列數個層面非常重要：
+ MFA 防護僅透過使用臨時安全性憑證供，而該憑證必須使用 `AssumeRole` 或 `GetSessionToken` 來取得。
+ 您無法搭配 AWS 帳戶根使用者 登入資料使用受 MFA 保護的 API 存取。
+ 無法搭配 U2F 安全性金鑰使用受 MFA 保護的 API 存取。
+ 聯合身分使用者無法獲指派 MFA 裝置以搭配 AWS 服務使用，因此無法存取 MFA 控制 AWS 的資源。(請查看下一要點。) 
+ 傳回暫時登入資料的其他 AWS STS API 操作不支援 MFA。對於 `AssumeRoleWithWebIdentity`和 `AssumeRoleWithSAML`，使用者由外部提供者進行驗證， AWS 無法判斷該提供者是否需要 MFA。對於 `GetFederationToken`，MFA 不一定要與特定使用者相關聯。
+ 同樣地，長期憑證 (IAM 使用者存取金鑰和根使用者存取金鑰) 無法用於受 MFA 保護的 API 存取，因為此類憑證不會過期。
+ 也可以在沒有 MFA 資訊的情況下呼叫 `AssumeRole` 與 `GetSessionToken`。在此情況下，呼叫者將取回臨時安全性憑證，但這些臨時憑證的工作階段資訊不會顯示使用 MFA 進行身分驗證的使用者。
+ 若要建立 API 操作的 MFA 防護，可將 MFA 條件加入到政策。政策必須包含 `aws:MultiFactorAuthPresent` 條件索引鍵，才能強制使用 MFA。對於跨帳戶委派，該角色的信任政策必須包含條件索引鍵。
+ 當您允許另一個 AWS 帳戶 存取您帳戶中的資源時，資源的安全性取決於受信任帳戶的組態 （另一個帳戶，而不是您的帳戶）。即使您要求多重要素驗證，也是如此。有權建立虛擬 MFA 裝置的可信帳戶中的任何身分都可以建構 MFA 宣告，以滿足角色信任政策的該部分。在允許另一個帳戶的成員存取需要多重要素驗證 AWS 的資源之前，您應該確保信任帳戶的擁有者遵循安全最佳實務。例如，信任的帳戶應該限制存取敏感 API 操作 (例如 MFA 裝置管理 API 操作) 至特定的信任身分。
+ 如果政策包含 MFA 條件，則在以下情況下將拒絕請求：使用者未進行 MFA 身分驗證或使用者提供了無效的 MFA 裝置識別碼或無效的 TOTP。

## 使用案例：跨帳戶委派的 MFA 防護
<a name="MFAProtectedAPI-cross-account-delegation"></a>

在此案例中，您想要將存取權委派給另一個帳戶中的 IAM 使用者，但前提是使用者已使用 AWS MFA 裝置進行身分驗證。如需有關跨帳戶委派的詳細資訊，請參閱 [角色術語和概念](id_roles.md#id_roles_terms-and-concepts)。

假設您有一個帳戶 A (擁有要存取的資源的信任帳戶)，其 IAM 使用者 Anaya 擁有管理員許可。她希望對帳戶 B (可信任的帳戶) 中的使用者 Richard 授予存取權，但希望確保 Richard 在擔任該角色之前已使用 MFA 進行身分驗證。

1. 在信任帳戶 A 中，Anaya 會建立名為 的 IAM 角色，`CrossAccountRole`並將角色信任政策中的委託人設定為帳戶 B 的帳戶 ID。信任政策會將 AWS STS 許可授予 `AssumeRole`動作。Anaya 也將 MFA 條件加入到信任政策中，如以下範例中所示。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": {
       "Effect": "Allow",
       "Principal": {"AWS": "ACCOUNT-B-ID"},
       "Action": "sts:AssumeRole",
       "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
     }
   }
   ```

------

1. Anaya 在該角色新增一個許可政策，以指定允許該角色執行的操作。具有 MFA 防護的角色許可政策與任何其他角色許可政策沒有差別。以下範例顯示 Anaya 新增到角色的政策；它允許假定的使用者在帳戶 A 中的 `Books` 資料表上執行任何 Amazon DynamoDB 動作。此政策也允許 `dynamodb:ListTables` 動作，而這是在主控台中執行動作的必要項目。
**注意**  
該許可政策不包含 MFA 條件。了解 MFA 身分驗證僅用於確定使用者是否可以擔任此角色這點非常重要。在使用者擔任此角色後，將不會進行進一步的 MFA 檢查。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "TableActions",
               "Effect": "Allow",
               "Action": "dynamodb:*",
               "Resource": "arn:aws:dynamodb:*:111122223333:table/Books"
           },
           {
               "Sid": "ListTables",
               "Effect": "Allow",
               "Action": "dynamodb:ListTables",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 在受信任帳戶 B 中，管理員會確定 IAM 使用者 Richard 已設定 AWS MFA 裝置，而且他知道裝置的 ID。如果是硬體 MFA 裝置，則裝置 ID 是序號，或如果是虛擬 MFA 裝置，裝置是 ARN。

1. 在帳戶 B 中，管理員將以下政策連接到使用者 Richard (或該使用者所在的群組)，該政策允許使用者呼叫 `AssumeRole` 動作。資源被設定到 Anaya 在第 1 步中所建立的角色 ARN。注意，該政策不包含 MFA 條件。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "sts:AssumeRole"
               ],
               "Resource": [
                   "arn:aws:iam::111122223333:role/CrossAccountRole"
               ]
           }
       ]
   }
   ```

------

1. 在帳戶 B 中，Richard (或 Richard 正在執行的應用程式) 呼叫 `AssumeRole`。API 呼叫包含要擔任角色的 ARN (`arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole`)、MFA 裝置的 ID 和 Richard 從其裝置中取得的目前 TOTP。

   當 Richard 呼叫 時`AssumeRole`， AWS 判斷他是否擁有有效的登入資料，包括 MFA 的需求。如果是這種情況，Richard 將成功取得角色，並且可在使用角色的臨時憑證時對帳戶 A 中名為 `Books` 的表格執行任何 DynamoDB 動作。

   有關呼叫 `AssumeRole` 的程式之範例，請參閱 [使用 MFA 身分驗證呼叫 AssumeRole](id_credentials_mfa_sample-code.md#MFAProtectedAPI-example-assumerole)。

## 使用案例：目前帳戶中 API 操作存取的 MFA 防護
<a name="MFAProtectedAPI-user-mfa"></a>

在此案例中，您應該確保 中的使用者只有在使用 AWS MFA 裝置驗證使用者時 AWS 帳戶 ，才能存取敏感的 API 操作。

假設您擁有帳戶 A，其中包含一組需要使用 EC2 執行個體的開發人員。普通開發人員可以使用執行個體，但他們未獲得 `ec2:StopInstances` 或 `ec2:TerminateInstances` 操作的許可。您希望僅允許幾個可信任的使用者執行這些「破壞性」特權操作，因此您將 MFA 防護加入到允許這些敏感 Amazon EC2 動作的政策中。

在此使用案例中，使用者 Sofía 是可信任的使用者之一。使用者 Anaya 是帳戶 A 中的管理員。

1. Anaya 確保 Sofía 已設定 AWS MFA 裝置，且 Sofía 知道裝置的 ID。如果是硬體 MFA 裝置，則裝置 ID 是序號，或如果是虛擬 MFA 裝置，裝置是 ARN。

1. Anaya 建立一個名為 `EC2-Admins` 的群組並將使用者 Sofía 加入到該群組中。

1. Anaya 將以下政策連接到 `EC2-Admins` 群組。此政策授予使用者呼叫 Amazon EC2 `StopInstances` 與 `TerminateInstances` 動作的許可，但前提是該使用者已使用 MFA 進行身分驗證。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [{
       "Effect": "Allow",
       "Action": [
         "ec2:StopInstances",
         "ec2:TerminateInstances"
       ],
       "Resource": ["*"],
       "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
     }]
   }
   ```

------

1. 
**注意**  
要讓此政策生效，使用者必須先登出，然後再次登入。

   如果使用者 Sofía 需要停止或終止 Amazon EC2 執行個體，她 (或執行中的應用程式) 會呼叫 `GetSessionToken`。此 API 操作傳遞 MFA 裝置的 ID，以及 Sofía 從其裝置取得的目前 TOTP。

1. 使用者 Sofía (或 Sofía 正在使用的應用程式) 使用由 `GetSessionToken` 提供的臨時憑證來呼叫 Amazon EC2 `StopInstances` 或者 `TerminateInstances` 動作。

   有關呼叫 `GetSessionToken` 的程式之範例，請參閱本文件後述的 [使用 MFA 身分驗證呼叫 GetSessionToken](id_credentials_mfa_sample-code.md#MFAProtectedAPI-example-getsessiontoken)。

## 使用案例：擁有以資源為基礎的政策之資源的 MFA 防護
<a name="MFAProtectedAPI-resource-policies"></a>

在此案例中，您是 S3 儲存貯體、SQS 佇列或 SNS 主題的擁有者。您想要確保來自任何存取資源 AWS 帳戶 的使用者都經過 AWS MFA 裝置驗證。

此使用案例介紹了一種提供跨帳戶 MFA 防護的方法，無需使用者先擔任角色。在此情況下，若符合三個條件，使用者便可存取資源。使用者必須通過 MFA 的身分驗證，能夠從 `GetSessionToken` 取得臨時安全性憑證，並且在資源政策所信任的帳戶中。

假設您在帳戶 A 中並建立一個 S3 儲存貯體。您想要將此儲存貯體的存取權授予位於數個不同 中的使用者 AWS 帳戶，但前提是這些使用者已使用 MFA 進行身分驗證。

在此方案中，使用者 Anaya 是帳戶 A 中的管理員。使用者 Nikhil 是帳戶 C 中的 IAM 使用者。

1. 在帳戶 A 中，Anaya 建立一個名為 `Account-A-bucket` 的儲存貯體。

1. Anaya 將儲存貯體政策加入到儲存貯體。該政策允許帳戶 A、帳戶 B 或帳戶 C 中的所有使用者執行儲存貯體中的 Amazon S3 `PutObject` 和 `DeleteObject` 動作。該政策包含 MFA 條件。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [{
       "Effect": "Allow",
       "Principal": {"AWS": [
         "ACCOUNT-A-ID",
         "ACCOUNT-B-ID",
         "ACCOUNT-C-ID"
       ]},
       "Action": [
         "s3:PutObject",
         "s3:DeleteObject"
       ],
       "Resource": ["arn:aws:s3:::ACCOUNT-A-BUCKET-NAME/*"],
       "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
     }]
   }
   ```

------
**注意**  
Amazon S3 (僅) 針對*根*帳戶存取提供「MFA 刪除」功能。在您設定儲存貯體的版本控制狀態時，可啟用 Amazon S3 MFA Delete 功能。Amazon S3 MFA Delete 功能不適用於 IAM 使用者，在管理時獨立於 MFA 防護的 API 存取。即使 IAM 使用者有刪除儲存貯體的許可，但在啟用 Amazon S3 MFA Delete 功能時，也無法執行刪除。如需有關 Amazon S3 MFA Delete 的詳細資訊，請參閱 [MFA Delete](https://docs.aws.amazon.com/AmazonS3/latest/dev/MultiFactorAuthenticationDelete.html)。

1. 在帳戶 C 中，管理員確定使用者 Nikhil 以 AWS MFA 裝置設定，而且知道裝置的 ID。如果是硬體 MFA 裝置，則裝置 ID 是序號，或如果是虛擬 MFA 裝置，裝置是 ARN。

1. 在帳戶 C 中，Nikhil (或該使用者正在執行的應用程式) 呼叫 `GetSessionToken`。此呼叫包括 MFA 裝置的 ID 或 ARN 以及 Nikhil 從其裝置中取得的目前 TOTP。

1. Nikhil (或 Nikhil 正在使用的應用程式) 使用由 `GetSessionToken` 傳回的暫時憑證來呼叫 Amazon S3 `PutObject` 動作，上傳檔案到 `Account-A-bucket`。

   有關呼叫 `GetSessionToken` 的程式之範例，請參閱本文件後述的 [使用 MFA 身分驗證呼叫 GetSessionToken](id_credentials_mfa_sample-code.md#MFAProtectedAPI-example-getsessiontoken)。
**注意**  
`AssumeRole` 傳回的暫時憑證在此案例中則不會運作。雖然使用者可以提供 MFA 資訊以取得角色，`AssumeRole` 傳回的暫時憑證不會包含 MFA 資訊。有了這項資訊，才能符合政策中的 MFA 條件。