使用 Azure Active Directory 和 亚马逊云科技 Lambda 向 亚马逊云科技 Transfer Family 进行身份验证

作者:山姆·埃利斯 | 202

注意(2023 年 5 月 11 日): 此博客文章中提供的示例解决方案不支持 Azure 活动目录的多重身份验证 (MFA)。


跨多个系统大规模管理用户可能成为一个耗时的过程,给系统管理员增加了不必要的负担。当客户操作在不同的内部和外部合作伙伴之间共享数据的文件传输工作负载时,用户管理变得越来越复杂。想象一下,一家拥有数十个在彼此之间传输数据的系统的公司。如果每个系统都有自己的用户管理,则必须在每个系统中以 1:1 的方式为每个用户创建唯一的用户。如果有权访问系统的一名员工离开公司,则必须将他们的用户从每个系统中删除。

为了解决这个问题,各公司希望通过将文件传输系统集成到其企业身份提供商 (IdP) 中来联合用户身份。使用企业 IdP 允许管理员在其 IdP 中集中管理用户,然后允许联合访问不同的系统。将用户从 IdP 中移除也会删除他们对公司内部系统和应用程序的访问权限,从而提高和简化安全性。

亚马逊云科技 Transfer Fam ily 是一项完全托管的服务,可轻松扩展 亚马逊云科技 上的重复文件传输工作负载。该服务允许您将文件直接存储在 亚马逊 S3 或 亚马逊 EFS 上, 并使用 SFTP、FTPS 和 FTP 来访问它们。亚马逊云科技 Transfer Family 提供多种管理用户身份的选项,因此您可以灵活地满足需求。

在这篇博客中,我概述了 亚马逊云科技 Transfer Family 身份验证选项,并提供了一个使用 亚马逊云科技 Transfer Family 的自定义 Lambda 身份提供商选项与 Azure AD 集成的示例架构。在本文的最后,您将了解 亚马逊云科技 Transfer Family 如何帮助您与所选的 IdP 集成,以消除不必要的管理负担并改善组织的安全状况,如上例所述。

亚马逊云科技 Transfer Family 认证概述

亚马逊云科技 Transfer Family 提供 服务托管用户 选项,但也提供与 亚马逊云科技 目录服务 亚马逊云科技 管理的微软 Active Directory (AD) 、亚马逊云科技 Lambda 定制 IdP 和亚马逊 API Gatew ay 定制 IdP 的集成。 图 1 汇总 了 亚马逊云科技 Transfer 系列的身份验证选项和支持的功能。你可以将自己的代码带有 Lambda 和 API Gateway 的自定义 IdP 选项,这样你就可以与 Okta、OneLogin、微软 Azure Active Directory (Azure AD) 等身份提供商,或者集成包含身份验证和授权逻辑的自定义数据存储。Lambda 自定义 IdP 选项允许您直接调用 Lambda 函数,而无需承担配置和管理 API 网关的开销。

Figure 1-Table of AWS Transfer Familys authentication options and supported features

图 1:亚马逊云科技 Transfer 系列的身份验证选项和支持的功能表

在这篇文章中,我们提供了一个参考架构,用于使用亚马逊云科技 Transfer Family的Lambda自定义 IdP 选项将你的 亚马逊云科技 Transfer Family 服务器与 Azure AD 集成。我们提供了一个示例 亚马逊云科技 Lambda 函数,其中包含用于对 Azure AD 用户进行身份验证的代码,并授权该用户获得 亚马逊云科技 Transfer Family 服务器的 S3 存储桶的读写权限。当你完成这篇文章后,你将能够使用集成了 Azure AD 的 Lambda 自定义 IdP 来部署 亚马逊云科技 Transfer Family。在此过程中,您将有示例可供构建,以便您的组织可以将文件传输工作负载的用户集中管理到企业 IdP。

亚马逊云科技 Transfer Family Lambda 自定义 IdP 认证和授权

在本节中,我们描述了使用 Lambda 自定义 IdP 选项时 亚马逊云科技 Transfer Family 的身份验证和授权工作流程。

亚马逊云科技 Transfer Family 的 Lambda 自定义 IdP 选项会调用您提供的用于与 IdP 集成的自定义代码。亚马逊云科技 Transfer Family 在由 S3 支持时使用 A WS 身份和访问管理 (IAM) 角色和会话策略授权用户会话,在 EFS 支持 时使用 POSIX 文件权限

图 2 是一个示意图,描述了使用 Lambda 自定义 IdP 选项时 亚马逊云科技 Transfer Family 的身份验证和授权工作流程。

  1. 亚马逊云科技 Transfer Family 用户通过其 SFTP 客户端发起登录或传输请求。
  2. 亚马逊云科技 Transfer Family 通过包含所提供的证书的事件调用 Lambda 函数。
  3. Lambda 函数的逻辑评估证书并使用 HTTP 200 响应进行响应,包括 IAM 角色 和可选的 会话策略。
  4. IAM 角色和会话策略授权用户的会话。

Figure 2-Diagram of AWS Transfer Family Lambda custom IdP option

图 2:亚马逊云科技 Transfer Family Lambda 自定义 IdP 选项示意图

在本文提供的示例架构中,有一个 IAM 角色授权所有经过身份验证的用户。使用 Lambda 自定义 IdP 选项,您可以自定义授权逻辑以适合您的用例。例如,您的 Lambda 函数可以使用 Azure AD 用户声明(例如组成员资格)从逻辑上确定会话策略和 IAM 角色。

示例架构和演练

在本节中,我们将讨论带有 Lambda 自定义 IdP 和 Azure AD 的 亚马逊云科技 Transfer Family 示例架构、先决条件、使用 CloudFormation 模板部署解决方案以及测试 亚马逊云科技 Transfer Family 服务器的步骤。我们将在本文后面介绍清理示例资源的步骤。

图 3 显示了本文中提供的 亚马逊云科技 Transfer 系列采用 Azure AD 示例架构的 Lambda 自定义 IdP 的用户身份验证和授权工作流程。

  1. 亚马逊云科技 Transfer Family 用户使用其 Azure AD 证书(用户名和密码)通过其 SFTP 客户端发起登录或传输请求。
  2. 亚马逊云科技 Transfer Family 通过包含所提供的证书的事件调用 Lambda 函数。
  3. Lambda 函数向 亚马逊云科技 Secrets Manager 发出请求,要求检索所需的
    Azure AD 客户端 ID 和 Azure AD 域名。密钥管理器用于安全地存储 Azure AD 客户端 ID 和 Azure AD 域名的值。
  4. Lambda 函数向 Azure AD 的图形 API 发出请求以检查凭据是否有效,并通过在请求中指定客户端 ID 和 Azure AD 域名来连接到指定的 Azure AD 应用程序。
  5. 如果凭据有效,Azure AD 会向 Lambda 返回带有用户声明的令牌。如果成功检索到令牌,它将提供 IAM 角色和会话策略。
  6. Lambda 函数使用上一步中的 IAM 角色和会话策略作为对 亚马逊云科技 Transfer Family 的 HTTP 200 响应来响应第二步中发起的请求。
  7. 用户通过 SFTP 协议向 亚马逊云科技 Transfer Family 服务器进行身份验证,该协议由 Lambda 函数提供的 IAM 角色和会话策略授权。

在第五步中,如果传递给 Azure AD 的证书无效,则 亚马逊云科技 Transfer Family 会在最终用户尝试连接时以登录失败错误来响应他们的请求。在幕后,Azure AD 返回失败的登录响应,Lambda 函数会记录错误、退出并向 亚马逊云科技 Transfer Family 返回空响应。

Figure 3-Diagram of sample architecture for AWS Transfer Family Lambda custom IdP option using Azure AD

图 3:使用 Azure AD 的 亚马逊云科技 Transfer Family Lambda 自定义 IdP 选项的示例架构示意图

先决条件

  1. 一个 亚马逊云科技 账户。有关说明,请参阅 创建 亚马逊云科技 账户
  2. 授权对 亚马逊云科技 Transfer Family、Lambda 和 S3 执行 IAM 操作。
  3. 一个 S3 存储桶。有关说明,请参阅 创建存储桶 。您将需要此存储桶的名称来部署您的 CloudFormation 堆栈。
  4. 一个 Azure AD 企业应用程序(Azure AD 应用程序)。必须使用 “授予 管理员同意” 配置 Azure AD 应用程序,为该目录 授予 读取 API 权限 。 还 必须在 Azure AD 应用程序 的 高级设置 启用 公共客户端流 。记下 Azure AD 应用程序中的以下属性,因为部署你的 CloudFormation 堆栈将需要这些属性。请注意,此示例解决方案不支持多因素身份验证 (MFA)。
    1. Azure AD 域名(例如@example .com)
    2. Azure AD 客户端 ID
  5. Azure AD 用户已添加到 Azure AD 应用程序中,因此你可以使用 亚马逊云科技 Transfer Family 测试身份验证。
  6. 您选择的 SFTP 客户端。有关更多信息,请参阅 使用客户端 传输文件
  7. (可选)要获得部署 CloudFormation 模板的最低权限授权,您可以使用以下 IAM 策略创建 亚马逊云科技 Clou dFormation 服务角色 。为此,您必须创建 IAM 策略 和 IAM 角色。您将将 IAM 策略附加到 IAM 角色,然后稍后在配置 CloudFormation 堆栈选项时选择此角色。您无需替换以下 IAM 策略中的任何值。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "LambdaModify",
            "Effect": "Allow",
            "Action": [
                "lambda:AddPermission",
                "lambda:RemovePermission",
                "lambda:GetFunction",
                "lambda:ListTags"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "LambdaCreate",
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:TagResource"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "LambdaDelete",
            "Effect": "Allow",
            "Action": [
                "lambda:DeleteFunction"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "IAMModify",
            "Effect": "Allow",
            "Action": [
                "iam:DeleteRole",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:GetRolePolicy",
                "iam:ListRoleTags",
                "iam:ListPolicyTags"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "IAMCreate",
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:TagRole"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "IAMGetRole",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "IAMPassRole",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": [
                        "lambda.amazonaws.com",
                        "transfer.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Sid": "SecretsCreateDelete",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:DeleteSecret",
                "secretsmanager:TagResource"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "SecretsCreate",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:CreateSecret"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "TransferDescribeAndDeleteServer",
            "Effect": "Allow",
            "Action": [
                "transfer:DeleteServer",
                "transfer:DescribeServer",
                "transfer:ListTagsForResource"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        },
        {
            "Sid": "TransferCreateServer",
            "Effect": "Allow",
            "Action": [
                "transfer:CreateServer",
                "transfer:TagResource"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/blogOrigin": "TransferFamilyAzureADIdP"
                }
            }
        }
    ]
}

7。(可选;续):为了对运行CloudFormation模板及后续操作的IAM委托人进行最低权限授权,本文使用以下 亚马逊云科技 托管策略和下面的客户托管策略进行了测试。在客户托管策略中,您需要替换 $ {AWS:: accountID}、$ {my-bucket-name} 和 $ {my-cloudformation-service-role-nam e} 的值。

亚马逊云科技 托管策略:

  • awsTransfer只读访问权限
  • 亚马逊云科技 Cloud Formation 完全访问权限

客户管理政策:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ViewS3BucketsWithoutErrors",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "InteractWithMyBucketAndTransferBucket",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::${my-bucket-name}*"
            ]
        },
        {
            "Sid": "UploadCloudFormationTemplate",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:CreateBucket",
                "s3:PutBucket*",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::cf-template*"
        },
        {
            "Sid": "CleanUpResults",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::${my-bucket-name}/home*"
            ]
        },
        {
            "Sid": "ListRolesForCloudFormationDeployment",
            "Effect": "Allow",
            "Action": [
                "iam:ListRoles"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "IAMRoleForCloudFormationDeployment",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::${AWS::AccountId}:role/${my-cloudformation-service-role-name}"
            ],
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "cloudformation.amazonaws.com"
                }
            }
        }
    ]
}

部署 CloudFormation 堆栈

在本节中,您将部署 亚马逊云科技 CloudFormation 堆栈来创建以下资源:

  • Azure AD 客户端 ID 的密钥管理器密钥
  • Azure AD 域名的密钥管理器密钥
  • 适用于所有经过身份验证的 亚马逊云科技 Transfer Family 用户的 IAM 角色
  • 具有 IAM 策略的 IAM 角色允许 Lambda 函数访问密钥管理器和 CloudWatch 日志
  • IAM 角色允许 亚马逊云科技 Transfer Family 访问云观日志
  • 使用 Azure AD 对用户进行身份验证的 Lambda 函数
  • 亚马逊云科技 Transfer Family 服务器将 Lambda 函数引用为其自定义 IdP
  • Lambda 资源策略允许 亚马逊云科技 Transfer Family 调用自定义身份提供商 Lambda 函数的权限

请注意,此 CloudFormation 模板已在 亚马逊云科技 区域 us-east-1 和 us-west-2 中进行了测试。 请注意,将其部署到您的 亚马逊云科技 账户会产生费用。本文后面将介绍清理资源的步骤,因此除了使用此示例解决方案的时间外,您不会承担任何费用。

要部署 CloudFormation,请执行以下步骤:

1。 下载这篇文章的 CloudFormation 模板 t ransfer-family-azure-active-director

2。在 亚马逊云科技 CloudFormation 控制台 上 ,选择 创建堆栈

3。选择 “ 上传模板文件 ” ,然后选择 “ 选择文件” 上传 t ransfer-family-azure-active-directory.yaml

4。在 指定堆栈详细信息 页面上,输入堆栈名称 Azu readsFTP。在同一页面上,有三个参数:

a. 对于 AzureClientID ,请输入先决条件部分中的 Azure AD 客户端 ID。

b. 对于 AzureDomain ,请输入先决条件部分中的 Azure AD 域名。

c. 对于 s3BucketName ,请在您的 亚马逊云科技 账户中以及与运行 CloudFormation 堆栈的同一 亚马逊云科技 区域中输入 S3 存储桶名称。(在这篇文章中,我们使用存储桶名称值,比如 my-bucket-n ame)。选择 “ 下一步 ” 。

5。在 “ 配置堆栈选项 ” 页面上,选择 “ 下一步 ” 。

a.(可选)如果您使用最低权限的 CloudFormation 服务角色,请在 “配置堆栈选项” 页面的 “权限” 部分下选择该角色的名称。

6。在 审核页面 上 ,选择 我承认 亚马逊云科技 CloudFormation 可能会创建 IAM 资源 然后选择 创建 堆栈。

该脚本运行并更改为 CREATE_COMPLETE 状态所需的时间不到 5 分钟。 如果您在同一 亚马逊云科技 账户和区域中两次部署堆栈,则某些资源将已经存在,并且该过程会失败并显示一条消息,表明该资源已经存在。

测试身份验证并使用您的 亚马逊云科技 Transfer Family 服务器

在本节中,你将使用你的 Azure AD 用户凭证向 亚马逊云科技 Transfer Family 服务器进行身份验证。对于我的 SFTP 客户端,我将使用 Mac OS 标配的 SFTP 命令行客户端。请注意,这是您可以在 亚马逊云科技 Transfer Family 服务器上使用的众多客户端之一,有关 亚马逊云科技 Transfer Family 支持的客户端的更多信息,请参阅 使用客户端 传输文件

  1. 使用链接导航到 亚马逊云科技 Transfer Famil y 控制台 ,或者在 亚马逊云科技 管理控制台的搜索栏中搜索 亚马逊云科技 Transfer Family 控制台,如 图 4 所示

Figure 4-Search result for AWS Transfer Family in AWS management console

图 4:在 亚马逊云科技 管理控制台中搜索 亚马逊云科技 Transfer Family 的结果

  1. 选择您的 CloudFormation 堆栈创建的 亚马逊云科技 Transfer Family 服务器的服务器 ID,如图 5 所 示

Figure 5-AWS Transfer Family Servers table

图 5:亚马逊云科技 Transfer Family Servers 表

  1. 记下 终端节点 详情 部分 下的 终端 节点,如 图 6 所示。 您将在下一步中使用它连接到 亚马逊云科技 Transfer Family。

Figure 6-AWS Transfer Family Endpoint

图 6:亚马逊云科技 Transfer Family 终端节点

  1. 打开终端并运行 sftp 客户端。你可以运行下面的命令,我还会在屏幕截图中提供输出, 如图 7 所示

打开您的终端,使用以下命令使用您的用户名和 亚马逊云科技 Transfer Family 服务器终端节点进行连接,并在提示您时输入密码。请注意,你必须将用户名替换为你的 Azure AD 用户名(比如 我的用户 ),将 亚马逊云科技 Tr ansfer Family 服务器端点替换为服务器端点(如 s-123456789012. server。transfer.us-west-2.amazonaws.com)。

sftp <username>@<endpoint>

使用以下 SFTP 命令将文件放到您的 亚马逊云科技 Transfer Family 服务器上。请注意,您必须将文件名替换为计算机上的本地文件(如 test.txt )。

put <path-to-local-file>

您可以列出 亚马逊云科技 Transfer Family 目录中的内容,以确保您的文件已上传。

ls

您可以使用以下命令关闭 SFTP 会话。

exit

Figure 7-Screenshot of example SFTP client interaction

图 7:示例 SFTP 客户端交互的屏幕截图

  1. 浏览到 S3 控制台 并选择您的 S3 存储桶。默认情况下,示例架构的 Lambda 函数根据用户的用户名(例如 m y-bucket-name/home/username/)为其提供主目录。 图 8 是浏览到与该主目录关联的 S3 前缀的屏幕截图,您在步骤 4 中上传的文件是该前缀下的对象。

Figure 8-Amazon S3 home directory prefix with test.txt object

图 8:带有 test.txt 对象的亚马逊 S3 主目录前缀

正在清理

在这篇文章中,你创建了几个产生成本的组件。为避免将来产生费用,请按照以下步骤移除资源:

  1. 导航到您用于测试的 S3 存储桶,然后删除在测试 亚马逊云科技 Transfer Family 服务器后创建的所有上传文件。有关如何 删除上传任何文件时创建的测试用户主目录的指南,请参阅删除文件夹 。使用默认模板时,S3 前缀将是 my-bucket -n ame/home/username/。在此步骤中请谨慎行事。除非您在 S3 存储桶上 使用版本控制 ,否则无法撤消删除 S3 对象的操作。
  2. CloudFormation 控制台 中 ,选择名为 AzureadsFTP 的堆栈,选择删除 ,然后确认。

摘要

在这篇文章中,我介绍了如何使用 亚马逊云科技 Transfer Family 的 Lambda 自定义 IdP 选项通过 Azure AD 应用程序对用户进行身份验证。示例架构包括使用 Azure AD 对用户进行身份验证并使用 IAM 角色授权的代码,允许您将用户从 Azure AD IdP 联合到 亚马逊云科技 Transfer Family,并集中管理文件传输工作负载的用户。集中管理用户可以带来许多好处,包括提高安全性和消除对文件传输工作负载的不当管理工作。你可以扩展此代码以适合你的特定用例,例如根据 Azure AD 组成员资格或其他声明向用户授权自定义策略。你可以使用 亚马逊云科技 管理控制台 、亚马逊云科技 CLI、 AP I、软件开发工具包或 亚马逊云科技 Cloud F orm ation 开始使用 AW S Transfer Family。

感谢您阅读这篇博客文章!如果您对亚马逊云科技 Transfer Family认证选项有疑问,请随时在评论部分发表评论。祝大楼愉快!

Sam Ellis

山姆·埃利斯

山姆·埃利斯是亚马逊网络服务的高级解决方案架构师。他与州和地方政府的 亚马逊云科技 客户合作,帮助他们采用云技术并建设未来。工作之余,他喜欢与家人共度时光、到户外、讲故事和演奏音乐。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。