本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 Amazon API Gateway 整合您的身份提供商
本主题介绍如何使用 Amazon Lambda 函数来支持 API Gateway 方法。如果您需要集成身份提供商,RESTfulAPI或者想要利用其功能来处理地理封锁或 Amazon WAF 速率限制请求,请使用此选项。
使用API网关集成身份提供商时的限制
-
此配置不支持自定义域。
-
此配置不支持私有API网关URL。
如果您需要其中任何一个,则可以使用 Lambda 作为身份提供商,无需API网关。有关详细信息,请参阅Amazon Lambda 用于集成您的身份提供商。
使用API网关方法进行身份验证
你可以创建一个API网关方法,用作 Transfer Family 的身份提供者。这种方法为您提供了一种高度安全的创建和提供方式APIs。使用 API Gateway,您可以创建HTTPS终端节点,以便以更高的安全性传输所有来API电。有关API网关服务的更多详细信息,请参阅API网关开发者指南。
APIGateway 提供了一种名为的授权方法AWS_IAM
,该方法基于内部 Amazon 使用的 Amazon Identity and Access Management (IAM) 为您提供相同的身份验证。如果您启用身份验证AWS_IAM
,则只有具有明确调用权限的呼叫者API才能访问API该API网关方法。
要将您的API网关方法用作 Transfer Family 的自定义身份提供者,请启用IAM您的API网关方法。在此过程中,您需要为IAM角色提供 Transfer Family 使用您的网关的权限。
注意
为了提高安全性,您可以配置 Web 应用程序防火墙。 Amazon WAF 是一种 Web 应用程序防火墙,允许您监控转发到 Amazon API Gateway 的HTTP和HTTPS请求。有关详细信息,请参阅添加 Web 应用程序防火墙。
使用 API Gateway 方法对 Transfer Family 进行自定义身份验证
-
创建 Amazon CloudFormation 堆栈。要实现此目的,应按照以下步骤进行:
注意
堆栈模板已更新为使用BASE64编码密码:有关详细信息,请参阅。对 Amazon CloudFormation 模板的改进
-
在 https://console.aws.amazon.com/cloudformat
ion 上打开 Amazon CloudFormation 控制台。 -
按照Amazon CloudFormation 用户指南中的选择 Amazon CloudFormation 堆栈模板中的现有模板部署堆栈的说明进行操作。
-
使用以下基本模板之一创建 Amazon Lambda支持的 API Gateway 方法,以便在 Transfer Family 中用作自定义身份提供者。
-
默认情况下,您的 API Gateway 方法用作自定义身份提供者,使用硬编码SSH(Secure Shell)密钥或密码对单个服务器中的单个用户进行身份验证。部署后,您可以修改 Lambda 函数代码以执行不同的操作。
-
默认情况下,你的 API Gateway 方法会根据 Secrets Manager 中格式
aws/transfer/
的条目进行身份验证。此外,该密钥必须包含返回给 Transfer Family 的所有用户属性的键值对。部署后,您可以修改 Lambda 函数代码以执行不同的操作。有关更多信息,请参阅博客文章启用密码身份验证以供 Amazon Transfer Family 使用 Amazon Secrets Managerserver-id
/username
。 -
你的 API Gateway 方法与 Okta 集成,作为 Transfer Family 中的自定义身份提供者。有关更多信息,请参阅博客文章:使用 Amazon Transfer Family将 Okta 用作身份提供程序
。
-
部署其中一个堆栈是将自定义身份提供程序集成到 Transfer Family 工作流程的最简单方法。每个堆栈都使用 Lambda 函数来支持基于APIAPI网关的方法。然后,您可以在 Transfer Family 中将您的API方法用作自定义身份提供者。默认情况下,Lambda 函数对使用
MySuperSecretPassword
密码myuser
调用的单个用户进行身份验证。部署后,您可以编辑这些凭证或更新 Lambda 函数代码以执行不同的操作。重要
我们建议您编辑默认的用户和密码凭证。
部署堆栈后,您可以在 CloudFormation 控制台的 Outputs 选项卡上查看有关堆栈的详细信息。这些详细信息包括堆栈的 Amazon 资源名称 (ARN)、堆栈创建的IAM角色以及您的新网关的。ARN URL
注意
如果您使用自定义身份提供商选项为用户启用基于密码的身份验证,并且启用了 Gatewa API y 提供的请求和响应日志,Gateway 会将用户的密码记录到您的 Amazon Logs 中。API CloudWatch 我们建议不要在生产环境中使用此日志。有关更多信息,请参阅《API网API关开发者指南》中的在 Gateway 中设置 CloudWatch API登录。
-
-
检查服务器的API网关方法配置。要实现此目的,应按照以下步骤进行:
-
打开API网关控制台,网址为https://console.aws.amazon.com/apigateway/
。 -
选择模板生成的转移自定义身份提供者基本 Amazon CloudFormation 模板API。您可能需要选择您的区域才能看到您的网关。
-
在资源窗格中,选择GET。以下屏幕截图显示了正确的方法配置。
此时,您的API网关已准备就绪,可以部署了。
-
-
在 “操作” 中,选择 “部署” API。对于部署阶段,选择 prod,然后选择部署。
成功部署 API Gateway 方法后,在 “阶段” > “阶段详细信息” 中查看其性能,如以下屏幕截图所示。
注意
复制出现在屏幕顶部的调用URL地址。下一步可能需要它。
-
打开 Amazon Transfer Family 控制台,网址为https://console.aws.amazon.com/transfer/
。 -
在你创建堆栈时,应该已经为你创建了 Transfer Family。如果不是,请使用以下步骤配置您的服务器。
选择“创建服务器”以打开“创建服务器”页面。在 “选择身份提供商” 中,选择 “自定义”,然后选择 “使用 Amazon API Gateway 连接到您的身份提供商”,如以下屏幕截图所示。
-
在提供 Amazon API Gateway URL 文本框中,粘贴您在本过程的步骤 3 中创建的API网关终端节点的调用URL地址。
-
在 “角色” 中,选择由 Amazon CloudFormation 模板创建的IAM角色。此角色允许 Transfer Family 调用你的API网关方法。
调用角色包含您在步骤 1 中为创建的堆栈选择的堆栈名称。 Amazon CloudFormation 格式如下:
。CloudFormation-stack-name
-TransferIdentityProviderRole-ABC123DEF456GHI
-
填写其余的方框,然后选择“创建服务器”。有关创建服务器的其余步骤的详细信息,请参阅 配置SFTPFTPS、或FTP服务器端点。
实现你的API网关方法
要为 Transfer Family 创建自定义身份提供者,您的API网关方法必须实现资源路径为的单个方法/servers/
。serverId
/users/username
/config
和serverId
值来自RESTful资源路径。此外,在方法请求中添加username
sourceIp
和protocol
作为URL查询字符串参数,如下图所示。
注意
此用户名长度最少为 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网关方法应始终返回HTTP状态码200
。任何其他HTTP状态码都表示访问时出错API。
Amazon S3 示例响应
示例响应正JSON文是以下格式的 Amazon S3 文档。
{ "Role": "IAM role with configured S3 permissions", "PublicKeys": [ "ssh-rsa
public-key1
", "ssh-rsapublic-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":[""] }
亚马逊回复EFS示例
示例响应正文是 Amazon 的以下格式的JSON文档EFS。
{ "Role": "
IAM role with configured EFS permissions
", "PublicKeys": [ "ssh-rsapublic-key1
", "ssh-rsapublic-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 中配置用户策略的更多信息,请参阅 管理访问控制。
默认 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证书与或者(如果FTP证书共享SFTP或FTPS公开)隔离开来,则您的工作负载使用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 CloudFormation 模板的改进
已对已发布 CloudFormation模板的API网关界面进行了改进。现在,模板在网BASE64关上使用编码的API密码。如果没有此增强功能,您的现有部署将继续运行,但不允许使用基本美国字符集之外的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
检查堆栈的模板是否是最新的
在 https://console.aws.amazon.com/cloudformat
ion 上打开 Amazon CloudFormation 控制台。 从堆栈列表中选择您的堆栈。
在详细信息面板中,选择模板选项卡。
-
寻找以下内容:
搜索
RequestTemplates
并确保你有以下行:"password": "$util.escapeJavaScript($util.base64Decode($input.params('PasswordBase64'))).replaceAll("\\'","'")",
搜索
RequestParameters
并确保你有以下行:method.request.header.PasswordBase64: false
如果您没有看到更新的行,请编辑您的堆栈。有关如何更新 Amazon CloudFormation 堆栈的详细信息,请参阅《用户指南》中的Amazon CloudFormation修改堆栈模板。