

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 Amazon API Gateway 方法设置为自定义身份提供商
<a name="gateway-api-tutorial"></a>

本教程演示了如何设置 Amazon API Gateway 方法并将其用作自定义身份提供商，将文件上传到 AWS Transfer Family 服务器。本教程仅使用[基本堆栈模板](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-basic-apig.template.yml)和其他基本功能作为示例。

**Topics**
+ [先决条件](#prereq-api-gateway-tutorial)
+ [步骤 1：创建 CloudFormation 堆栈](#create-cf-stack)
+ [步骤 2：检查服务器的 API Gateway 方法配置。](#deploy-api-gateway)
+ [步骤 3：查看 Transfer Family 服务器详细信息](#create-transfer-server)
+ [步骤 4：测试您的用户是否可以连接到服务器](#test-user-server-connect)
+ [步骤 5：测试 SFTP 连接和文件传输](#test-sftp-connection)
+ [步骤 6：限制对存储桶的访问权限](#example-bucket)
+ [如果使用 Amazon EFS，请更新 Lambda](#lambda-posix)

## 先决条件
<a name="prereq-api-gateway-tutorial"></a>

在中创建 Transfer Family 资源之前 CloudFormation，请创建您的存储空间和用户角色。

**要指定存储并创建用户角色**

1. 根据您使用的存储，请参阅以下文档：
   + 要创建 Amazon S3 存储桶，请参阅*Amazon Simple Storage Service 用户指南*中的[如何创建 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-bucket-overview.html)
   + 要创建 Amazon EFS 文件系统，请参阅[配置 Amazon EFS 文件系统](configure-storage.md#requirements-efs)。

1. 要创建用户角色，请参阅 [创建 IAM 角色和策略](requirements-roles.md)

在下一部分中创建 CloudFormation 堆栈时，您将输入存储和用户角色的详细信息。

## 步骤 1：创建 CloudFormation 堆栈
<a name="create-cf-stack"></a>

**使用提供的模板创建 AWS CloudFormation 堆栈**

1. 打开 CloudFormation 控制台，网址为[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 选择**创建堆栈**，然后选择**使用新资源（标准）**。

1. 在 “**先决条件-准备模板**” 窗格中，**选择选择现有模板**。

1. 复制此链接，即[基本堆栈模板](https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-basic-apig.template.yml)，然后将其粘贴**到 Amazon S3 URL** 字段中。

1. 单击**下一步**。

1. 指定参数，包括堆栈的名称。务必执行以下操作：
   + 替换**UserName**和的默认值**UserPassword**。
   + 对于 **UserHomeDirectory**，请输入您之前创建的存储（Amazon S3 存储桶或 Amazon EFS 文件系统）的详细信息。
   + 将默认**UserRoleArn**角色替换为您之前创建的用户角色。 AWS Identity and Access Management (IAM) 角色必须具有相应的权限。有关 IAM 角色和存储桶策略示例，请参阅 [步骤 6：限制对存储桶的访问权限](#example-bucket)。
   + 如果要使用公钥而不是密码进行身份验证，请在**UserPublicKey1**字段中输入您的公钥。首次使用 SFTP 连接到服务器时，将提供私有密钥而不是密码。

1. 选择**下一步**，然后在**配置堆栈选项**页面上再次选择**下一步**。

1. 查看您正在创建的堆栈的详细信息，然后选择**创建堆栈**。
**注意**  
在页面底部的**功能**下，您必须确认 CloudFormation 可能会创建 IAM 资源。

## 步骤 2：检查服务器的 API Gateway 方法配置。
<a name="deploy-api-gateway"></a>

**注意**  
为了提高安全性，可以配置 Web 应用程序防火墙。 AWS WAF 是一种 Web 应用程序防火墙，可让您监视转发到 Amazon API Gateway 的 HTTP 和 HTTPS 请求。有关更多信息，请参阅 [添加 Web 应用程序防火墙](web-application-firewall.md)。

**不要启用 API Gateway 缓存**  
将 API Gateway 方法用作 Transfer Family 的自定义身份提供者时，请勿为其启用缓存。缓存对身份验证请求不恰当且无效，因为：  
每个身份验证请求都是唯一的，需要实时响应，而不是缓存的响应
缓存没有任何好处，因为 Transfer Family 永远不会向 API Gateway 发送重复或重复的请求
启用缓存将导致 API Gateway 使用不匹配的数据进行响应，从而导致对身份验证请求的响应无效

**检查服务器的 API Gateway 方法配置并部署它**

1. <a name="step_invoke_url"></a>

   打开 API Gateway 控制台，网址为[https://console.aws.amazon.com/apigateway/](https://console.aws.amazon.com/apigateway/)。

1. 选择模板生成的**转移自定义身份提供商基本 CloudFormation 模板 API**。

1. 在**资源**窗格中，选择**获取**，然后选择 **方法请求**。

1. 在**操作**，选择**部署 API**。对于**部署阶段**，选择 **prod**，然后选择**部署**。

   成功部署 API Gateway 方法后，在**阶段编辑器**部分查看其性能。
**注意**  
复制显示在页面顶部的**调用 URL** 地址。在下一步骤中，您将需要该值。

## 步骤 3：查看 Transfer Family 服务器详细信息
<a name="create-transfer-server"></a>

当你使用模板创建 CloudFormation 堆栈时，会自动创建一个 Transfer Family 服务器。

**要查看您的 Transfer Family 服务器详细信息**

1. 打开 CloudFormation 控制台，网址为[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 选择您创建的堆栈。

1. 选择**资源**选项卡。  
![显示创建 CloudFormation 堆栈期间创建的资源列表的屏幕，其中突出显示了 Transfer Family 服务器的详细信息。](http://docs.aws.amazon.com/zh_cn/transfer/latest/userguide/images/apig-find-server-id.png)

   服务器 ARN 显示在该行的 “**物理 ID**” 列中。**TransferServer**服务器 ID 包含在 ARN 中，例如 **s-11112222333344445**。

1. 打开 AWS Transfer Family 控制台 [https://console.aws.amazon.com/transfer/](https://console.aws.amazon.com/transfer/)，然后在 “**服务器**” 页面上，选择新服务器。

   服务器 ID 与中为**TransferServer**资源显示的 ID 相匹配 CloudFormation。

## 步骤 4：测试您的用户是否可以连接到服务器
<a name="test-user-server-connect"></a>

**要测试您的用户是否可以连接到服务器，请使用 Transfer Family 控制台**

1. 打开 AWS Transfer Family 控制台，网址为[https://console.aws.amazon.com/transfer/](https://console.aws.amazon.com/transfer/)。

1. 在**服务器**页面上，选择您的新服务器，选择**操作**，然后选择**测试**。

1. 在**用户名**字段和**密码**字段中输入登录凭证的文本。这些是您在部署 CloudFormation 堆栈时设置的值。

1. 对于**服务器协议**，请选择 **SFTP**，对于**源 IP**，请输入**127.0.0.1**。

1. 选择**测试**。

   如果用户身份验证成功，则测试将返回一个 `StatusCode: 200` HTML 响应和一个包含用户角色和权限详细信息的 JSON 对象。例如：

   ```
   {
       "Response": "{\"Role\": \"arn:aws:iam::{{123456789012}}:role/{{my-user-role}}\",\"HomeDirectory\": \"/${transfer:HomeBucket}/\"}",
       "StatusCode": 200,
       "Message": "",
       "Url": "https://{{1a2b3c4d5e}}.execute-api.{{us-east-2}}.amazonaws.com/prod/servers/s-{{1234abcd5678efgh0}}/users/{{myuser}}/config"
   }
   ```

   如果测试失败，请将其中一个 API Gateway AWS 托管策略添加到您用于 API 的角色中。

## 步骤 5：测试 SFTP 连接和文件传输
<a name="test-sftp-connection"></a>

**测试 SFTP 连接**

1. 在 Linux 或 macOS 设备上，打开命令终端。

1. 根据您是使用密码还是密钥对进行身份验证，输入以下命令之一。
   + 如果您使用的是密码，请输入如下命令：

      ` sftp -o PubkeyAuthentication=no {{myuser}}@{{server-ID}}.server.transfer.{{region-code}}.amazonaws.com ` 

     出现提示时请输入密码。
   +  如果您使用的是密钥对，请输入如下命令：

     ` sftp -i {{private-key-file}} {{myuser}}@{{server-ID}}.server.transfer.{{region-code}}.amazonaws.com `
**注意**  
对于这些 `sftp` 命令，请插入 Transfer Family 服务器所在位置 AWS 区域 的代码。例如，如果您的服务器位于美国东部（俄亥俄州），请输入 **us-east-2**。

1.  `sftp>` 出现提示时，请确保您可以上传 (`put`)、下载 (`get`) 以及查看目录和文件（`pwd` 和 `ls`）。

## 步骤 6：限制对存储桶的访问权限
<a name="example-bucket"></a>

您可以限制谁能够访问特定 Amazon S3 存储桶。以下示例显示了要在 CloudFormation 堆栈和为用户选择的策略中使用的设置。

在此示例中，我们为 CloudFormation 堆栈设置了以下参数：
+ **CreateServer**: `true`
+ **UserHomeDirectory**: `/amzn-s3-demo-bucket1`
+ **UserName**: `myuser`
+ **UserPassword**: `MySuperSecretPassword`
**重要**  
这是密码示例。在配置 API Gateway 方法时，请务必输入一个强密码。
+ **UserPublicKey1**: `{{your-public-key}}`
+ **UserRoleArn**: `arn:aws:iam::{{role-id}}:role/myuser-api-gateway-role`

``**UserPublicKey1**是您作为密钥对（key pair）的一部分生成的公 public/private 钥。

`{{role-id}}` 对于您创建的用户角色而言是唯一的。附加到 `myuser-api-gateway-role` 的策略如下：

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:DeleteObjectVersion",
                "s3:DeleteObject",
                "s3:PutObjectAcl",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*"
        }
    ]
}
```

 要使用 SFTP 连接到服务器，请在提示符下输入以下命令之一。
+ 如果您使用密码进行身份验证，请运行如下命令：

   ` sftp -o PubkeyAuthentication=no {{myuser}}@{{transfer-server-ID}}.server.transfer.{{region-id}}.amazonaws.com` 

  出现提示时请输入密码。
+  如果您使用密钥对进行身份验证，请运行如下命令：

  ` sftp -i {{private-key-file}} myuser@{{transfer-server-ID}}.server.transfer.{{region-id}}.amazonaws.com `

**注意**  
对于这些`sftp`命令，请使用您的 Transf AWS 区域 er Family 服务器所在位置的 ID。例如，如果您的服务器位于美国东部（俄亥俄州），请使用 `us-east-2`。

 在 `sftp` 提示符下，您将被定向到主目录，您可以通过运行 `pwd` 命令来查看该目录。例如：

```
sftp> pwd
Remote working directory: /amzn-s3-demo-bucket1
```

用户无法查看主目录之上的任何目录。例如：

```
sftp> pwd
Remote working directory: /amzn-s3-demo-bucket1
sftp> cd ..
sftp> ls
Couldn't read directory: Permission denied
```

## 如果使用 Amazon EFS，请更新 Lambda
<a name="lambda-posix"></a>

 如果您选择 Amazon EFS 作为 Transfer Family 服务器的存储选项，则需要编辑堆栈的 lambda 函数。

**向你的 Lambda 函数添加 Posix 配置文件**

1. 打开 Lambda 控制台，网址为。[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)

1.  选择先前创建的 Lambda 函数。Lambda 函数的格式为 **{{stack-name}}-GetUserConfigLambda-{{lambda-identifier}}**，其中{{stack-name}}是 CloudFormation 堆栈名称，{{lambda-identifier}}也是函数的标识符。

1.  在**代码**选项卡中，选择 **index.js** 以显示该函数的代码。

1.  在 `response` 中，在 `Policy` 和 `HomeDirectory` 之间添加以下行：

    ` PosixProfile: {"Uid": {{uid-value}}, "Gid": {{gid-value}}}, ` 

    其中，{{uid-value}}和{{gid-value}}是分别代表用户 ID 和群组 ID 的 0 或大于整数。

   例如，添加 Posix 配置文件后，响应字段可能如下所示：

   ```
    response = {
         Role: 'arn:aws:iam::123456789012:role/api-gateway-transfer-efs-role', // The user will be authenticated if and only if the Role field is not blank
         Policy: '', // Optional JSON blob to further restrict this user's permissions
         PosixProfile: {"Gid": 65534, "Uid": 65534},
         HomeDirectory: '/fs-fab2c234' // Not required, defaults to '/'
       };
   ```