使用 Amazon API Gateway 整合您的身份提供程序 - Amazon Transfer Family
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

使用 Amazon API Gateway 整合您的身份提供程序

本主题介绍如何使用 Amazon Lambda 函数支持 API Gateway 方法。如果您需要 RESTful API 来集成您的身份提供商,或者您想使用 Amazon WAF 其功能来处理地理封锁或速率限制请求,请使用此选项。

使用 API Gateway 集成身份提供程序时的限制

  • 此配置不支持自定义域。

  • 此配置不支持私有 API Gateway 网址。

如果您需要其中任何一个,则可以使用 Lambda 作为身份提供程序,而无需使用 API Gateway。有关更多信息,请参阅 Amazon Lambda 用于整合您的身份提供商

使用 API Gateway 方法进行身份验证

您可以创建一个 API Gateway 方法,用作 Transfer Family 的身份提供程序。这种方法为您创建和提供 API 提供了一种高度安全的方式。使用 API Gateway,您可以创建 HTTPS 端点,以便以更高的安全性传输所有传入的 API 调用。有关 API Gateway 服务的更多详细信息,请参阅 API Gateway 开发者指南

API Gateway 提供了一种名为的授权方法AWS_IAM,该方法为您提供与内部 Amazon 使用的相同基于 Amazon Identity and Access Management (IAM) 的身份验证。如果您通过 AWS_IAM 启用身份验证,则只有具有调用 API 的明确权限的调用程序才能访问该 API 的 API Gateway 方法。

要将您的 API Gateway 方法用作 Transfer Family 的自定义身份提供程序,请为您的 API Gateway 方法启用 IAM。在此过程中,您需要为一个 IAM 角色提供 Transfer Family 使用您的网关的权限。

注意

为了提高安全性,可以配置 Web 应用程序防火墙。 Amazon WAF 是一种 Web 应用程序防火墙,可让您监视转发到 Amazon API Gateway 的 HTTP 和 HTTPS 请求。有关更多信息,请参阅 是一个 Web 应用程序防火墙。

使用您的 API Gateway 方法对 Transfer Family 进行自定义身份验证
  1. 创建 Amazon CloudFormation 堆栈。要实现此目的,应按照以下步骤进行:

    注意

    堆栈模板已更新为使用 Base64 编码的密码:有关详细信息,请参阅。对 Amazon CloudFormation 模板的改进

    1. 打开 Amazon CloudFormation 控制台,网址为 https://console.aws.amazon.com/cloudformation

    2. 按照Amazon CloudFormation 用户指南中的选择 Amazon CloudFormation 堆栈模板中的使用现有模板部署堆栈的说明进行操作。

    3. 使用以下基本模板之一创建 Amazon Lambda支持的 API Gateway 方法,以便在 Transfer Family 中用作自定义身份提供者。

    部署其中一个堆栈是将自定义身份提供程序集成到 Transfer Family 工作流程的最简单方法。每个堆栈都使用 Lambda 函数来支持基于 API Gateway 的 API 方法。然后,您可以在 Transfer Family 中使用您的 API 方法作为自定义身份提供程序。默认情况下,Lambda 函数对使用 MySuperSecretPassword 密码 myuser 调用的单个用户进行身份验证。部署后,您可以编辑这些凭证或更新 Lambda 函数代码以执行不同的操作。

    重要

    我们建议您编辑默认的用户和密码凭证。

    部署堆栈后,您可以在 CloudFormation 控制台的 Outputs 选项卡上查看有关堆栈的详细信息。这些详细信息包括堆栈的 Amazon 资源名称 (ARN)、堆栈创建的 IAM 角色的 ARN 以及您的新网关的 URL。

    注意

    如果您使用自定义身份提供商选项为用户启用基于密码的身份验证,并且启用了 API Gateway 提供的请求和响应日志,API Gateway 会将用户的密码记录到您的 Amazon 日志中。 CloudWatch 我们建议不要在生产环境中使用此日志。有关更多信息,请参阅《 CloudWatch API Gateway 开发者指南》中的 “在 API Gateway 中设置 API 日志”。

  2. 检查您的服务器的 API Gateway 方法配置。要实现此目的,应按照以下步骤进行:

    1. 打开 API Gateway 控制台,网址为:https://console.aws.amazon.com/apigateway/

    2. 选择模板生成的转移自定义身份提供商基本 Amazon CloudFormation 模板 API。您可能需要选择您的区域才能看到您的网关。

    3. 在 “资源” 窗格中,选择 GET。以下屏幕截图显示了正确的方法配置。

      API 配置详细信息,显示请求路径的方法配置参数和 URL 查询字符串的 。

    此时,您的 API Gateway 已准备好部署。

  3. 操作,选择部署 API。对于部署阶段,选择 prod,然后选择部署

    成功部署 API Gateway 方法后,在 “阶段” > “阶段详情” 中查看其性能,如以下屏幕截图所示。

    注意

    复制显示在屏幕顶部的调用 URL 地址。下一步可能需要它。

    暂存细节,突出显示调用网址。
  4. 打开 Amazon Transfer Family 控制台,网址为 https://console.aws.amazon.com/transfer/

  5. 在你创建堆栈时,应该已经为你创建了 Transfer Family。如果不是,请使用以下步骤配置您的服务器。

    1. 选择“创建服务器”以打开“创建服务器”页面。在“选择身份提供程序”中,选择“自定义”,然后选择“使用 Amazon API Gateway 连接到您的身份提供程序”,如以下屏幕截图所示。

      身份提供者屏幕,选择自定义身份提供商,并选择 API Gateway 来连接到您的身份提供商。
    2. 提供 Amazon API Gateway 网址文本框中,粘贴您在本过程的步骤 3 中创建的 API Gateway 端点的调用 URL 地址。

    3. 对于角色,选择由 Amazon CloudFormation 模板创建的 IAM 角色。此角色允许 Transfer Family 调用您的 API Gateway 方法。

      调用角色包含您在步骤 1 中为创建的堆栈选择的堆栈名称。 Amazon CloudFormation 格式如下:CloudFormation-stack-name-TransferIdentityProviderRole-ABC123DEF456GHI

    4. 填写其余的方框,然后选择“创建服务器”。有关创建服务器的其余步骤的详细信息,请参阅 配置 SFTP、FTPS 或 FTP 服务器端点

实施您的 API Gateway 方法

要为 Transfer Family 创建自定义身份提供程序,您的 API Gateway 方法必须实现资源路径为 /servers/serverId/users/username/config 的单个方法。serverIdusername 来自 RESTful 资源路径。此外,在方法请求中添加 sourceIpprotocol 作为 URL 查询字符串参数,如下图所示。

API Gateway 的资源屏幕显示了GET方法的详细信息。
注意

此用户名长度最少为 3 个字符,最多为 100 个字符。您可以在用户名中使用以下字符:a–z、A-Z、0–9、下划线 (_)、连字符 (-)、句点 (.) 和 at 符号 (@)。但是,用户名不能以连字符 (-)、句点 (.) 或 at 符号 (@) 开头。

如果 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": "/bucketName/path/to/home/directory" }
注意

策略会以 JSON 格式转义为字符串。例如:

"Policy": "{ \"Version\": \"2012-10-17\", \"Statement\": [ {\"Condition\": {\"StringLike\": {\"s3:prefix\": [\"user/*\", \"user/\"]}}, \"Resource\": \"arn:aws:s3:::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\":\"/MY-HOME-BUCKET\"}]", "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} }

您可以在 JSON 格式的 Lambda 函数中包含用户策略。有关在 Transfer Family 中配置用户策略的更多信息,请参阅 管理访问控制

默认 Lambda 函数

要实施不同的身份验证策略,请编辑您的网关使用的 Lambda 函数。为了帮助您满足应用程序的需求,您可以在 Node.js 中使用以下示例 Lambda 函数。有关更多信息, Amazon Lambda 开发人员指南 通过 Node.js 构建 Lambda 函数

以下示例 Lambda 函数使用您的用户名、密码(如果您正在执行密码身份验证)、服务器 ID、协议和客户端 IP 地址。您可以使用这些输入的组合来查找您的身份提供程序并确定是否应接受登录。

注意

如果您为服务器启用了多个协议,并且想要通过多个协议使用相同的用户名提供访问权限,则只要在身份提供程序中设置了相关协议的特定凭据,就可以这样做。

对于文件传输协议 (FTP),我们建议为 Secure Shell (SSH) 文件传输协议 (SFTP) 和 SSL (FTPS) 文件传输协议设置不同的凭证。我们建议为 FTP 保留单独的凭据,因为与 SFTP 和 FTPS 不同,FTP 以明文形式传输凭据。通过将 FTP 凭证与 SFTP 或 FTPS 隔离开来,如果共享或公开 FTP 凭证,则使用 SFTP 或 FTPS 的工作负载会保持安全。

此示例函数会返回角色和逻辑主目录详细信息以及公钥(如果它执行公钥身份验证)。

创建服务托管用户时,可以设置他们的主目录,无论是逻辑目录还是物理目录均是如此。同样,我们需要 Lambda 函数的结果来传达所需的用户物理或逻辑目录结构。您设置的参数取决于该 HomeDirectoryType 字段的值。

  • HomeDirectoryType 设置为 PATH — 然后,HomeDirectory 字段必须是您的用户可见的 Amazon S3 存储桶绝对前缀或 Amazon EFS 绝对路径。

  • HomeDirectoryType 设置为 LOGICAL — 请不要设置 HomeDirectory 字段。相反,我们设置了一个提供所需入口/目标映射的 HomeDirectoryDetails 字段,类似于服务托管用户的 HomeDirectoryDetails 参数中描述的值。

Lambda 函数示例 中列出了示例函数。

用于的 Lambda 函数 Amazon Secrets Manager

要 Amazon Secrets Manager 用作您的身份提供商,您可以使用示例 Amazon CloudFormation 模板中的 Lambda 函数。Lambda 函数使用您的凭证查询 Secrets Manager 服务,如果成功,则会返回指定的密钥。有关 Secrets Manager 的更多信息,请参阅《Amazon Secrets Manager 用户指南》https://docs.amazonaws.cn/secretsmanager/latest/userguide/intro.html

要下载使用此 Lambda 函数的示例 Amazon CloudFormation 模板,请访问提供的 Amazon S3 存储桶。 Amazon Transfer Family

对 Amazon CloudFormation 模板的改进

已发布的 CloudFormation模板已对 API Gateway 界面进行了改进。现在,这些模板在 API Gateway 中使用 Base64 编码的密码。如果没有此增强功能,您的现有部署可以继续运行,但不允许使用基本 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')" }
  • GetUserConfig资源必须更改RequestParameters为使用PasswordBase64标题(斜体行是更新的行):

    RequestParameters: method.request.header.PasswordBase64: false method.request.querystring.protocol: false method.request.querystring.sourceIp: false
检查堆栈的模板是否是最新的
  1. 打开 Amazon CloudFormation 控制台,网址为 https://console.aws.amazon.com/cloudformation

  2. 从堆栈列表中选择您的堆栈。

  3. 在详细信息面板中,选择模板选项卡。

  4. 寻找以下内容:

    • 搜索RequestTemplates并确保你有以下行:

      "password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
    • 搜索RequestParameters并确保你有以下行:

      method.request.header.PasswordBase64: false

如果您没有看到更新的行,请编辑您的堆栈。有关如何更新 Amazon CloudFormation 堆栈的详细信息,请参阅《用户指南》中的Amazon CloudFormation修改堆栈模板