

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

# 使用 Amazon API Gateway 整合您的身分提供者
<a name="authentication-api-gateway"></a>

本主題說明如何使用 AWS Lambda 函數來支援 API Gateway 方法。如果您需要 RESTful API 來整合身分提供者，或想要使用 AWS WAF 來利用其功能進行地理封鎖或速率限制請求，請使用此選項。

對於大多數使用案例，設定自訂身分提供者的建議方法是使用 [自訂身分提供者解決方案](custom-idp-toolkit.md)。

**使用 API Gateway 整合身分提供者的限制**
+ 此組態不支援自訂網域。
+ 此組態不支援私有 API Gateway URL。

如果您需要這些其中一項，您可以使用 Lambda 做為身分提供者，無需 API Gateway。如需詳細資訊，請參閱[使用 AWS Lambda 整合您的身分提供者](custom-lambda-idp.md)。

## 使用 API Gateway 方法進行驗證
<a name="authentication-custom-ip"></a>

您可以建立 API Gateway 方法，做為 Transfer Family 的身分提供者。此方法為您提供高度安全的方式來建立和提供 APIs。使用 API Gateway，您可以建立 HTTPS 端點，以便以更高的安全性傳輸所有傳入的 API 操作。如需 API Gateway 服務的詳細資訊，請參閱 [API Gateway 開發人員指南](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)。

API Gateway 提供名為 的授權方法`AWS_IAM`，它會根據 AWS Identity and Access Management (IAM) 為您提供與內部 AWS 相同的身分驗證。如果您使用 啟用身分驗證`AWS_IAM`，只有具有明確呼叫 API 許可的呼叫者才能到達該 API 的 API Gateway 方法。

若要使用 API Gateway 方法做為 Transfer Family 的自訂身分提供者，請為您的 API Gateway 方法啟用 IAM。在此程序中，您會為 IAM 角色提供 Transfer Family 使用閘道的許可。

**注意**  
為了提高安全性，您可以設定 Web 應用程式防火牆。 AWS WAF 是一種 Web 應用程式防火牆，可讓您監控轉送至 Amazon API Gateway 的 HTTP 和 HTTPS 請求。如需詳細資訊，請參閱[新增 Web 應用程式防火牆](web-application-firewall.md)。

**請勿啟用 API Gateway 快取**  
將 API Gateway 方法用作 Transfer Family 的自訂身分提供者時，請勿啟用 API Gateway 方法的快取。快取對身分驗證請求不適當且無效，因為：  
每個身分驗證請求都是唯一的，需要即時回應，而不是快取的回應
快取沒有好處，因為 Transfer Family 永遠不會將重複或重複的請求傳送至 API Gateway
啟用快取會導致 API Gateway 以不相符的資料回應，導致身分驗證請求的回應無效

**使用 API Gateway 方法搭配 Transfer Family 進行自訂身分驗證**

1. 建立 CloudFormation 堆疊。若要執行此作業：
**注意**  
堆疊範本已更新為使用 BASE64-encoded密碼：如需詳細資訊，請參閱 [CloudFormation 範本的改進](#base64-templates)。

   1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

   1. 遵循*AWS CloudFormation 《 使用者指南*》中選取 CloudFormation 堆疊範本中從現有範本部署堆疊的指示。 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-using-console-create-stack-template.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-using-console-create-stack-template.html)

   1. 使用下列其中一個基本範本來建立 AWS Lambda後端 API Gateway 方法，以做為 Transfer Family 中的自訂身分提供者。
      + [基本堆疊範本](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-basic-apig.template.yml)

        根據預設，您的 API Gateway 方法會做為自訂身分提供者使用硬式編碼 SSH （安全殼層） 金鑰或密碼來驗證單一伺服器中的單一使用者。部署之後，您可以修改 Lambda 函數程式碼，以執行不同的動作。
      + [AWS Secrets Manager 堆疊範本](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-secrets-manager-apig.template.yml)

        根據預設，您的 API Gateway 方法會根據 Secrets Manager 格式 的項目進行驗證`aws/transfer/server-id/username`。此外，秘密必須保留傳回 Transfer Family 的所有使用者屬性的鍵/值對。部署之後，您可以修改 Lambda 函數程式碼，以執行不同的動作。如需詳細資訊，請參閱部落格 [postEnable password authentication for AWS Transfer Family using AWS Secrets Manager](https://aws.amazon.com/blogs/storage/enable-password-authentication-for-aws-transfer-family-using-aws-secrets-manager-updated/)。
      + [Okta 堆疊範本](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-okta-apig.template.yml)

        您的 API Gateway 方法與 Okta 整合，做為 Transfer Family 中的自訂身分提供者。如需詳細資訊，請參閱部落格文章[使用 Okta 做為 的身分提供者 AWS Transfer Family](https://aws.amazon.com/blogs/storage/using-okta-as-an-identity-provider-with-aws-transfer-for-sftp/)。

   部署其中一個堆疊是將自訂身分提供者整合到 Transfer Family 工作流程的最簡單方法。每個堆疊都使用 Lambda 函數來支援以 API Gateway 為基礎的 API 方法。然後，您可以使用 API 方法做為 Transfer Family 中的自訂身分提供者。根據預設，Lambda 函數會使用密碼 `myuser`來驗證名為 的單一使用者`MySuperSecretPassword`。部署之後，您可以編輯這些登入資料或更新 Lambda 函數程式碼，以執行不同的動作。
**重要**  
我們建議您編輯預設使用者和密碼登入資料。

   部署堆疊之後，您可以在 CloudFormation 主控台的**輸出**索引標籤上檢視其詳細資訊。這些詳細資訊包括堆疊的 Amazon Resource Name (ARN)、堆疊建立的 IAM 角色 ARN，以及新閘道的 URL。
**注意**  
如果您使用自訂身分提供者選項為使用者啟用密碼型身分驗證，並啟用 API Gateway 提供的請求和回應記錄，API Gateway 會將使用者的密碼記錄到您的 Amazon CloudWatch Logs。我們不建議您在生產環境中使用此日誌。如需詳細資訊，請參閱[《 API Gateway 開發人員指南》中的在 API Gateway 中設定 CloudWatch API 記錄](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html)。 **

1. 檢查您伺服器的 API Gateway 方法組態。若要執行此作業：

   1. 在以下網址開啟 API Gateway 主控台：[https://console.aws.amazon.com/apigateway/](https://console.aws.amazon.com/apigateway/)。

   1. 選擇 CloudFormation 範本產生的 **Transfer Custom Identity Provider 基本範本 API**。您可能需要選取您的區域，才能查看您的閘道。

   1. 在**資源**窗格中，選擇 **GET**。下列螢幕擷取畫面顯示正確的方法組態。  
![\[API 組態詳細資訊，顯示請求路徑的方法組態參數，以及 URL 查詢字串的 。\]](http://docs.aws.amazon.com/zh_tw/transfer/latest/userguide/images/apig-config-method-fields.png)

   此時，您的 API 閘道已準備好進行部署。

1. 針對**動作**，選擇**部署 API**。針對**部署階段**，選擇 **prod**，然後選擇**部署**。

   成功部署 API Gateway 方法後，請在**階段 > ****階段詳細資訊**中檢視其效能，如下列螢幕擷取畫面所示。
**注意**  
複製出現在畫面頂端的**調用 URL** 地址。您可能需要它進行下一個步驟。  
![\[反白顯示調用 URL 的階段詳細資訊。\]](http://docs.aws.amazon.com/zh_tw/transfer/latest/userguide/images/apig-config-method-invoke.png)

1. 在 https：//[https://console.aws.amazon.com/transfer/](https://console.aws.amazon.com/transfer/) 開啟 AWS Transfer Family 主控台。

1. 當您建立堆疊時，應該已為您建立 Transfer Family。如果沒有，請使用下列步驟設定您的伺服器。

   1. 選擇**建立伺服器**以開啟**建立伺服器**頁面。針對**選擇身分提供者**，選擇**自訂**，然後選取**使用 Amazon API Gateway 連線到您的身分提供者**，如下列螢幕擷取畫面所示。  
![\[選取自訂身分提供者的身分提供者畫面，以及選取用於連線至身分提供者的 API Gateway。\]](http://docs.aws.amazon.com/zh_tw/transfer/latest/userguide/images/create-server-choose-idp-custom.png)

   1. 在**提供 Amazon API Gateway URL** 文字方塊中，貼上您在此程序的步驟 3 中建立的 API Gateway 端點的**調用 URL** 地址。

   1. 針對**角色**，選擇範本建立的 IAM 角色 CloudFormation 。此角色允許 Transfer Family 調用您的 API 閘道方法。

      調用角色包含您為步驟 1 中建立的 CloudFormation 堆疊選取的堆疊名稱。其格式如下：`CloudFormation-stack-name-TransferIdentityProviderRole-ABC123DEF456GHI`。

   1. 填寫剩餘的方塊，然後選擇**建立伺服器**。如需建立伺服器之其餘步驟的詳細資訊，請參閱 [設定 SFTP、FTPS 或 FTP 伺服器端點](tf-server-endpoint.md)。

## 實作您的 API Gateway 方法
<a name="authentication-api-method"></a>

若要為 Transfer Family 建立自訂身分提供者，您的 API Gateway 方法必須實作資源路徑為 的單一方法`/servers/serverId/users/username/config`。`serverId` 和 `username`值來自 RESTful 資源路徑。此外，請在**方法請求**中將 `sourceIp`和 新增`protocol`為 **URL 查詢字串參數**，如下圖所示。

![\[API Gateway 的資源畫面顯示GET方法詳細資訊。\]](http://docs.aws.amazon.com/zh_tw/transfer/latest/userguide/images/apig-config-method-request.png)


**注意**  
使用者名稱必須至少為 3 個字元，最多為 100 個字元。您可以在使用者名稱中使用下列字元：a–z、A-Z、0–9、底線 '\$1'、連字號 '-'、句點 '.' 和符號 '@'。使用者名稱開頭不能是連字號 '-'、句點 '.' 或符號 '@'。

如果 Transfer Family 嘗試為您的使用者進行密碼身分驗證，服務會提供`Password:`標頭欄位。如果沒有 `Password:` 標頭，Transfer Family 會嘗試使用公有金鑰身分驗證來驗證您的使用者。

當您使用身分提供者來驗證和授權最終使用者時，除了驗證其登入資料之外，您還可以根據最終使用者使用的用戶端 IP 地址來允許或拒絕存取請求。您可以使用此功能來確保儲存在 S3 儲存貯體或 Amazon EFS 檔案系統中的資料只能透過您指定為受信任的 IP 地址，透過支援的通訊協定存取。若要啟用此功能，您必須在查詢字串`sourceIp`中包含 。

如果您為伺服器啟用了多個通訊協定，並想要透過多個通訊協定使用相同的使用者名稱提供存取權，只要身分提供者已設定每個通訊協定的特定登入資料，您就可以這麼做。若要啟用此功能，您必須在 RESTful 資源路徑中包含 `protocol`值。

您的 API Gateway 方法應一律傳回 HTTP 狀態碼 `200`。任何其他 HTTP 狀態碼表示存取 API 時發生錯誤。

**Amazon S3 範例回應**  
回應內文範例是 Amazon S3 的 JSON 文件，格式如下。

```
{
 "Role": "IAM role with configured S3 permissions",
 "PublicKeys": [
     "ssh-rsa public-key1",
     "ssh-rsa public-key2"
  ],
 "Policy": "STS Assume role session policy",
 "HomeDirectory": "/amzn-s3-demo-bucket/path/to/home/directory"
}
```

**注意**  
 政策會以字串的形式逸出 JSON。例如：  

****  

```
"Policy":
"{
  \"Version\": \"2012-10-17\",
  \"Statement\":
     [
     {\"Condition\":
        {\"StringLike\":
            {\"s3:prefix\":
               [\"user/*\", \"user/\"]}},
     \"Resource\": \"arn:aws:s3:::amzn-s3-demo-bucket\",
     \"Action\": \"s3:ListBucket\",
     \"Effect\": \"Allow\",
     \"Sid\": \"ListHomeDir\"},
     {\"Resource\": \"arn:aws:s3:::*\",
        \"Action\": [\"s3:PutObject\",
        \"s3:GetObject\",
        \"s3:DeleteObjectVersion\",
        \"s3:DeleteObject\",
        \"s3:GetObjectVersion\",
        \"s3:GetObjectACL\",
        \"s3:PutObjectACL\"],
     \"Effect\": \"Allow\",
     \"Sid\": \"HomeDirObjectAccess\"}]
}"
```

下列範例回應顯示使用者具有邏輯主目錄類型。

```
{
   "Role": "arn:aws:iam::123456789012:role/transfer-access-role-s3",
   "HomeDirectoryType":"LOGICAL",
   "HomeDirectoryDetails":"[{\"Entry\":\"/\",\"Target\":\"/amzn-s3-demo-bucket1\"}]",
   "PublicKeys":[""]
}
```

**Amazon EFS 範例回應**  
回應內文範例是 Amazon EFS 的 JSON 文件，格式如下。

```
{
 "Role": "IAM role with configured EFS permissions",
 "PublicKeys": [
     "ssh-rsa public-key1",
     "ssh-rsa public-key2"
  ],
 "PosixProfile": {
   "Uid": "POSIX user ID",
   "Gid": "POSIX group ID",
   "SecondaryGids": [Optional list of secondary Group IDs],
 },
 "HomeDirectory": "/fs-id/path/to/home/directory"
}
```

`Role` 欄位顯示已成功進行身分驗證。執行密碼身分驗證時 （當您提供`Password:`標頭時），您不需要提供 SSH 公有金鑰。如果無法驗證使用者，例如，如果密碼不正確，您的方法應該傳回未`Role`設定的回應。這類回應的範例是空的 JSON 物件。

 下列範例回應顯示具有邏輯主目錄類型的使用者。

```
{
    "Role": "arn:aws:iam::123456789012:role/transfer-access-role-efs",
    "HomeDirectoryType": "LOGICAL",
    "HomeDirectoryDetails":"[{\"Entry\":\"/\",\"Target\":\"/faa1a123\"}]",
    "PublicKeys":[""],
    "PosixProfile":{"Uid":65534,"Gid":65534}
}
```

您可以在 Lambda 函數中包含 JSON 格式的使用者政策。如需在 Transfer Family 中設定使用者政策的詳細資訊，請參閱 [管理存取控制](users-policies.md)。

## 預設 Lambda 函數
<a name="authentication-lambda-examples-default"></a>

若要實作不同的身分驗證策略，請編輯閘道使用的 Lambda 函數。為了協助您滿足應用程式的需求，您可以在 Node.js 中使用下列範例 Lambda 函數。如需 Lambda 的詳細資訊，請參閱[AWS Lambda 開發人員指南](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)或使用 [ Node.js 建置 Lambda 函數。](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html)

下列範例 Lambda 函數會取得您的使用者名稱、密碼 （如果您執行密碼身分驗證）、伺服器 ID、通訊協定和用戶端 IP 地址。您可以使用這些輸入的組合來查詢您的身分提供者，並判斷是否應接受登入。

**注意**  
如果您為伺服器啟用了多個通訊協定，並希望透過多個通訊協定使用相同的使用者名稱提供存取權，只要身分提供者中已設定了通訊協定特定的登入資料，就可以這麼做。  
對於檔案傳輸通訊協定 (FTP)，我們建議您維護與 Secure Shell (SSH) 檔案傳輸通訊協定 (SFTP) 和透過 SSL 的檔案傳輸通訊協定 (FTPS) 不同的登入資料。我們建議您維護個別的 FTP 登入資料，因為與 SFTP 和 FTPS 不同，FTP 會以純文字傳輸登入資料。透過從 SFTP 或 FTPS 隔離 FTP 登入資料，如果共用或公開 FTP 登入資料，則使用 SFTP 或 FTPS 的工作負載會保持安全。

此範例函數會傳回角色和邏輯主目錄詳細資訊，以及公有金鑰 （如果執行公有金鑰身分驗證）。

當您建立服務受管使用者時，您可以設定其主目錄，無論是邏輯或實體。同樣地，我們需要 Lambda 函數結果來傳達所需的使用者實體或邏輯目錄結構。您設定的參數取決於 [https://docs.aws.amazon.com//transfer/latest/APIReference/API_CreateUser.html#TransferFamily-CreateUser-request-HomeDirectoryType](https://docs.aws.amazon.com//transfer/latest/APIReference/API_CreateUser.html#TransferFamily-CreateUser-request-HomeDirectoryType) 欄位的值。
+ `HomeDirectoryType` 設定為 `PATH` - 欄位`HomeDirectory`接著必須是使用者可見的絕對 Amazon S3 儲存貯體字首或 Amazon EFS 絕對路徑。
+ `HomeDirectoryType` 設定為 `LOGICAL` – *請勿*設定`HomeDirectory`欄位。相反地，我們會設定一個`HomeDirectoryDetails`欄位，提供所需的 Entry/Target 映射，類似於服務受管使用者 [https://docs.aws.amazon.com//transfer/latest/APIReference/API_CreateUser.html#TransferFamily-CreateUser-request-HomeDirectoryMappings](https://docs.aws.amazon.com//transfer/latest/APIReference/API_CreateUser.html#TransferFamily-CreateUser-request-HomeDirectoryMappings) 參數中所述的值。

範例函數會列在 中[Lambda 函數範例](custom-lambda-idp.md#lambda-auth-examples)。

## 搭配 使用的 Lambda 函數 AWS Secrets Manager
<a name="authentication-lambda-examples-secrets-mgr"></a>

若要使用 AWS Secrets Manager 做為您的身分提供者，您可以在範例 CloudFormation 範本中使用 Lambda 函數。Lambda 函數會使用您的登入資料查詢 Secrets Manager 服務，如果成功， 會傳回指定的秘密。如需 Secrets Manager 的詳細資訊，請參閱 [AWS Secrets Manager 使用者指南](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)。

若要下載使用此 Lambda 函數的範例 CloudFormation 範本，請前往 [提供的 Amazon S3 儲存貯 AWS Transfer Family](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-secrets-manager-apig.template.yml)體。

## CloudFormation 範本的改進
<a name="base64-templates"></a>

已改善已發佈的 CloudFormation 範本的 API Gateway 界面。範本現在搭配 API Gateway 使用 BASE64-encoded的密碼。如果沒有此增強功能，您現有的部署會繼續運作，但不允許使用基本 US-ASCII 字元集以外字元的密碼。

範本中啟用此功能的變更如下：
+ `GetUserConfigRequest AWS::ApiGateway::Method` 資源必須具有此`RequestTemplates`程式碼 （斜體行是更新的行）

  ```
  RequestTemplates:
     application/json: |
     {
        "username": "$util.urlDecode($input.params('username'))",
        "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
        "protocol": "$input.params('protocol')",
        "serverId": "$input.params('serverId')",
        "sourceIp": "$input.params('sourceIp')"
  }
  ```
+ 資源`RequestParameters`的 `GetUserConfig` 必須變更 才能使用 `PasswordBase64`標頭 （斜體行是更新的行）：

  ```
  RequestParameters:
     method.request.header.PasswordBase64: false
     method.request.querystring.protocol: false
     method.request.querystring.sourceIp: false
  ```

**檢查堆疊的範本是否為最新的**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 從堆疊清單中，選擇您的堆疊。

1. 從詳細資訊面板中，選擇**範本**索引標籤。

1. 尋找下列項目：
   + 搜尋 `RequestTemplates`，並確定您有此行：

     ```
     "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
     ```
   + 搜尋 `RequestParameters`，並確定您有此行：

     ```
     method.request.header.PasswordBase64: false
     ```

如果您沒有看到更新的行，請編輯您的堆疊。如需如何更新 CloudFormation 堆疊的詳細資訊，請參閱《 *AWS CloudFormation使用者指南*》中的[修改堆疊範本](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-get-template.html)。