作者:Roberto Migli Rafael Koike 和 Ron Cully日期:2023 年 12 月 7 日链接:高级 AWS IAM 身份中心 安全、身份与合规永久链接评论
2023年12月12日: 我们更新了这篇文章,澄清了您可以使用 stsauditcontext 和 stsidentitycontext 来创建增强身份的会话。
AWS 身份与访问管理 (IAM) 的角色是管理 Amazon Web Services (AWS) 云资源权限的有效方式。这些角色适用于那些工作负载静态的用户。然而,对于访问模式更为动态的用户,依赖角色可能会使管理员在配置角色和确保合适人员拥有合适权限时感到复杂。
处理动态工作队伍访问的常用解决方案是 OAuth 20 框架,允许将已认证用户的身份传递到资源服务。资源服务可以根据用户的属性或权限管理权限,而不是构建复杂的角色管理系统。最近,AWS IAM 身份中心引入了基于 OAuth 20 的可信身份传播,以支持动态访问模式。
在可信身份传播下,请求应用程序从 IAM 身份中心获取令牌,并将其传递给 AWS 资源服务。AWS 资源服务信任来自身份中心生成的令牌,并根据这些令牌授予权限。
如果您想要部署的应用程序使用外部 OAuth 授权服务器如 Okta Universal Directory 或 Microsoft Entra ID,但 AWS 服务使用 IAM 身份中心,该如何操作?如何将这些外部应用的令牌与 AWS 托管的应用程序一起使用?
在这篇博客中,我们将展示如何使用 IAM 身份中心的可信令牌发布者来解决这些挑战。您还将了解 IAM 身份中心和 OAuth 的基本知识,以及如何使用外部 OAuth 授权服务器。
IAM 身份中心作为您 AWS 云环境的集中身份服务。您可以将工作队伍用户引入 AWS,并从 AWS 之外的身份提供者IdP,如 Okta 或 Microsoft Entra进行身份验证,或者在 AWS 上创建和验证用户。
IAM 身份中心中的可信身份传播允许 AWS 工作者身份使用 OAuth 20,帮助需要在 AWS 服务中共享使用者身份的应用程序。在 OAuth 中,客户端应用程序和资源服务都信任同一个授权服务器。客户端应用程序为用户获取令牌,并将其发送到资源服务。由于这两个服务信任 OAuth 服务器,资源服务可以根据令牌识别用户并根据其身份设置权限。
AWS 应用程序直接与 IAM 身份中心进行身份验证: 身份中心将身份验证重定向到您的身份源,生成的令牌将被 AWS 管理的应用程序用于访问 AWS 服务。这是默认模式,因为支持可信身份传播的 AWS 服务将身份中心用作其授权服务器。
第三方非 AWS 应用程序在 AWS 之外进行身份验证通常是您的 IdP,然后访问 AWS 资源:在身份验证过程中,这些第三方应用程序从 AWS 之外的 OAuth 授权服务器获取令牌。此模式下,AWS 服务并未连接到与客户端应用程序相同的 OAuth 授权服务器。为启用此模式,AWS 引入了称为 Trusted Token IssuerTTI模型。
当 AWS 服务使用 IAM 身份中心作为其身份验证服务、目录和授权服务器时,使用令牌的 AWS 服务要求身份中心发放令牌。然而,大多数第三方应用程序通过外部 IdP 联合并从外部授权服务器获取令牌。尽管身份中心和外部授权服务器中的身份可能是同一用户,但它们在不同域中存在:一个在身份中心,另一个在外部授权服务器。这是为了管理与 AWS 服务的工人身份授权。
可信令牌发布者TTI功能提供了一种安全的方式,可以将来自外部 IdP 的一个身份与 IAM 身份中心中的另一个身份关联。
当使用第三方应用程序访问 AWS 服务时,第三方应用程序有一个外部 OAuth 授权服务器,而 IAM 身份中心则是 AWS 服务的 OAuth 授权服务器;它们各自拥有自己的用户域。身份中心 TTI 功能连接这两个系统,使得外部 OAuth 授权服务器的令牌可以与身份中心的令牌进行交换,从而允许 AWS 服务识别 AWS 用户域内的用户。TTI 是身份中心信任的外部 OAuth 授权服务器,用于提供第三方应用程序用于调用 AWS 服务的令牌,如图 1 所示。
TTI 涉及两个信任层次。首先,IAM 身份中心管理员必须添加 TTI,这样就可以进行令牌交换。这涉及将身份中心连接到外部 OAuth 授权服务器的 Open ID Connect (OIDC) 发现 URL,并定义外部 OAuth 授权服务器的用户与 IAM 身份中心中相应用户之间的基于属性的映射。其次,必须将需要交换外部生成的令牌的应用程序配置为使用 TTI。令牌交换的模型有两种:
受管 AWS 服务驱动令牌交换: 第三方应用程序使用 AWS 驱动程序或 API 访问受管 AWS 服务,例如通过 Amazon Redshift 驱动程序访问 Amazon Redshift。此模式仅在受管 AWS 服务被设计为接受和交换令牌时有效。应用程序通过 API 调用将外部令牌传递给 AWS 服务。AWS 服务随后调用 IAM 身份中心以交换外部令牌为身份中心令牌。该服务使用身份中心令牌确定相应的身份中心用户,并根据身份授权资源访问。
第三方应用程序驱动令牌交换: 未由 AWS 管理的第三方应用程序在调用 AWS 服务之前先将外部令牌交换为 IAM 身份中心令牌。这与上述第一种模型不同,在第一种模型中,交换令牌的应用程序是受管 AWS 服务。一个例子是第三方应用程序使用 Amazon Simple Storage Service (Amazon S3) 访问授权 来访问 S3。在此模式中,第三方应用程序从外部 OAuth 授权服务器获取令牌,然后调用身份中心以交换外部令牌为身份中心令牌。该应用程序可以使用身份中心令牌调用将身份中心作为其 OAuth 授权服务器的 AWS 服务。在这种情况下,身份中心管理员必须注册第三方应用程序并授权其交换来自 TTI 的令牌。
使用 TTI 时,IAM 身份中心信任 TTI 已经验证了用户并授权其使用 AWS 服务。这在来自外部 OAuth 授权服务器即 TTI的身份令牌或访问令牌中得以体现。
外部 OAuth 授权服务器TTI及其生成的令牌的要求如下:
该令牌必须是已签名的 JSON Web Token (JWT)。JWT 必须包含主题 (sub) 声明、受众 (aud) 声明、发布者 (iss)、用户属性声明和 JWT ID (JTI) 声明。 JWT 的主题是经过身份验证的用户,受众是一种表示用户可以使用的 AWS 服务的值。受众声明的值必须与交换令牌的应用程序中配置的值相匹配。发布者声明的值必须与 TTI 中配置的发布者 URL 的值匹配。令牌中必须包含一个声明,指定 IAM 身份中心可以用来查找对应用户的用户属性。JWT 令牌必须包含 JWT ID 声明。此声明用于帮助防止重放攻击。如果在初始交换完成后尝试进行新的令牌交换,IAM 身份中心将拒绝新的交换请求。
TTI 必须具有一个 IAM 身份中心可以用于获取密钥以验证 TTI 创建的 JWT 签名的 OIDC 发现 URL。身份中心在您配置的提供者 URL 后附加 /wellknown/openidconfiguration 以确定从哪里获取签名密钥。
注意: 通常,您用作 IAM 身份中心身份源的 IdP 是您的 TTI。但是,您的 TTI 并不一定非要是身份中心所用的 IdP。如果来自 TTI 的用户可以映射到身份中心中的用户,则可以进行令牌交换。您可以为单个身份中心实例配置最多 10 个 TTI。
一元云购官网您的 OAuth 授权服务器服务即 TTI提供一种方法来授权用户访问 AWS 服务。当用户登录到客户端应用程序时,OAuth 授权服务器生成一个 ID 令牌或访问令牌,其中包括主题用户和受众用户可以访问的 AWS 服务。当第三方应用程序访问 AWS 服务时,受众必须包括 AWS 服务的标识符。然后,第三方客户端应用程序将此令牌传递给 AWS 驱动程序或 AWS 服务。
要使用 IAM 身份中心并将来自 TTI 的外部令牌交换为身份中心令牌,您必须配置将与身份中心交换令牌的应用程序,以使用一个或多个 TTI。此外,作为配置过程的一部分,您还必须指定希望在外部令牌中使用的受众值。
如果应用程序是受管 AWS 服务,AWS 会执行大部分配置过程。例如,Amazon Redshift 管理员将 Amazon Redshift 连接到 IAM 身份中心,然后将特定 Amazon Redshift 集群连接到身份中心。该 Amazon Redshift 集群交换令牌并且必须配置为这样做,这可以通过 Amazon Redshift 管理控制台或 API 完成,不需要额外配置。
如果应用程序是第三方并且不是由 AWS 管理的,您的 IAM 身份中心管理员必须注册该应用程序并进行令牌交换配置。例如,假设您创建了一个从 Okta Universal Directory 获取令牌并调用 S3 访问授权的应用程序。身份中心管理员必须将此应用程序添加为客户管理应用程序,并必须授予该应用程序交换令牌的权限。

要创建新的 TTI,请转到 AWS 管理控制台 IAM 身份中心中身份验证设置的 可信令牌发布者 部分图 2。在这一部分,我将演示如何使用控制台创建新的 TTI 以与我的 Okta IdP 交换令牌,在那里我已经创建了我的 OIDC 应用以配合我的新 IAM 身份中心应用程序使用。
TTI 使用发布者 URL 来发现 OpenID 配置。由于我使用的是 Okta,我可以验证我的 IdP 发现 URL 是否可以通过 https//{myoktadomain}oktacom/wellknown/openidconfiguration 访问。我还可以验证 OpenID 配置 URL 是否响应包含 jwksuri 属性的 JSON,该属性包含列出我的 IdP 用于签署 JWT 令牌的密钥的 URL。可信令牌发布者要求这两个 URL 是公开可访问的。
然后,我在 映射属性 部分配置我想要用于将 Okta 用户的身份与 IAM 身份中心中的用户关联的属性。我可以从 Okta 颁发的 OIDC 身份令牌获取属性:
json{ sub 00u22603n2TgCxTgs5d7 email ltmaskedgt ver 1 iss https//ltmaskedgtoktacom aud 123456nqqVBTdtk7890 iat 1699550469 exp 1699554069 jti IDMojsBne1SlND7tCMtZPbpiei9pgoJsOmCiHkyEhUj8 amr [ pwd ] idp ltmaskedgt authtime 1699527801 athash ZFteB9l4MXc9virpYaul9A}
我请求一个具有额外电子邮件范围的令牌,因为我希望使用这个属性与我的 IAM 身份中心用户的电子邮件进行匹配。在大多数情况下,您的身份中心用户通过使用 SCIM 协议自动配置 与您的中央身份提供者进行同步。在这种情况下,您可以使用身份中心外部 ID 属性与 oid 或 sub 属性进行匹配。TTI 唯一的要求是这些属性必须在两个 IdP 之间创建一对一的映射关系。
现在我已经创建了我的 TTI,我可以将其与我的 IAM 身份中心应用程序关联。如前所述,有两种用例。对于受管 AWS 服务驱动的令牌交换用例,使用特定于服务的接口来完成此操作。例如,我可以像图 3 所示那样将我的 TTI 与 Amazon Redshift 一起使用:
我选择 Okta 作为此集成使用的 TTI,现在需要配置应用程序将用于接受令牌的 aud 声明值。我可以在 IdP 端创建应用程序时找到它在这个例子中,该值为 123456nqqVBTdtk7890,我可以通过使用上面的 OIDC 身份令牌示例来获取它。
我还可以使用 AWS 命令行界面 (AWS CLI) 为 IAM 身份中心应用程序配置适当的应用程序授权:
bashaws sso putapplicationgrant applicationarn ltmyapplicationarngt granttype urnietfparamsoauthgranttypejwtbearer grant { JwtBearer { AuthorizedTokenIssuers [ { TrustedTokenIssuerArn ltmyttiarngt AuthorizedAudiences [ 123456nqqVBTdtk7890 ] } ] } }
对于 AWS 服务驱动的用例,您的 IdP 和 IAM 身份中心之间的令牌交换是由服务本身自动执行的。对于第三方应用程序驱动的令牌交换,例如在构建自己的身份中心应用程序与 S3 访问授权的过程中,您的应用程序通过 IAM 身份中心 OIDC API 动作 CreateTokenWithIAM 执行令牌交换:
bashaws ssooidc createtokenwithiam clientid ltmyapplicationarngt granttype urnietfparamsoauthgranttypejwtbearer assertion ltjwtfromidpgt
此操作由 IAM 主体执行,然后使用该结果与 AWS 服务进行交互。
如果成功,结果如下所示:
json{ accessToken ltidcaccesstokengt tokenType Bearer expiresIn 3600 idToken ltjwtidcidentitytokengt issuedTokenType urnietfparamsoauthtokentypeaccesstoken scope [ stsidentitycontext openid aws ]}
范围属性的值因您与之交互的 IAM 身份中心应用程序而异,因为它定义了与该应用程序关联的权限。
您还可以检查 idToken 属性,因为它是 JWT 编码的:
json{ awsidentitystoreid d123456789 sub 93445892f00170788c387f2b978f686f awsinstanceaccount 12345678912 iss https//identitycenteramazonawscom/ssoins69870e74abba8440 stsauditcontext