SAML在 Amazon Cognito 用户池中启动会话 - Amazon Cognito

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

SAML在 Amazon Cognito 用户池中启动会话

Amazon Cognito 支持服务提供商启动(SP 启动)的单点登录 () 和 IDP 发起的单点登录。SSO SSO作为最佳安全实践,请在用户池SSO中实施 SP 启动方案。SAMLV2.0 技术概述的第 5.1.2 节描述了 SP 启动的。SSOAmazon Cognito 是您的应用程序的身份提供商 (IdP)。该应用程序是为经过身份验证的用户检索令牌的服务提供程序 (SP)。但是,当您使用第三方 IdP 对用户进行身份验证时,Amazon Cognito 就是 SP。当您的 SAML 2.0 用户使用 SP 启动的流程进行身份验证时,他们必须始终首先向 Amazon Cognito 提出请求,然后重定向到 IdP 进行身份验证。

对于某些企业使用案例,对内部应用程序的访问从企业 IdP 托管的控制面板上的书签开始。当用户选择书签时,IdP 会生成SAML响应并将其发送到 SP,以便通过应用程序对用户进行身份验证。

您可以在用户池中配置 SAML IdP 以支持 IdP 启动。SSO当您支持 IDP 发起的身份验证时,Amazon Cognito 无法验证它是否已请求收到SAML的响应,因为 Amazon Cognito 不会通过请求启动身份验证。SAML在 SP 启动中SSO,Amazon Cognito 会设置状态参数,以验证针对原始SAML请求的响应。使用 SP 发起的登录,您还可以防范跨站请求伪造 ()。CSRF

使用 SP 启动的登录 SAML

最佳做法是实现 service-provider-initiated(由 SP 发起的)用户池登录。Amazon Cognito 会启动您的用户的会话并将他们重定向到您的 IdP。使用这种方法,您可以最大限度地控制谁提出登录请求。在某些条件下,您也可以允许 IDP 发起的登录。

以下过程显示了用户如何通过提供商完成 SP 启动的用户池登录。SAML

Amazon Cognito S SAML P 发起的登录的身份验证流程图。
  1. 您的用户在登录页面输入他们的电子邮件地址。要确定您的用户是否重定向到其 IdP,您可以在定制化应用程序中收集他们的电子邮件地址,或者在 Web 视图中调用托管 UI。您可以将托管 UI 配置为显示电子邮件地址列表 IdPs 或仅提示输入电子邮件地址。

  2. 您的应用程序调用您的用户池重定向端点,并请求使用与应用程序对应的客户端 ID 和与用户对应的 IdP ID 进行会话。

  3. Amazon Cognito 使用元素中的SAML请求(可选签名)将您的用户重定向到 IdP。AuthnRequest

  4. IdP 以交互方式对用户进行身份验证,或者使用浏览器 cookie 中记住的会话对用户进行身份验证。

  5. IdP 将您的用户重定向到您的用户池SAML响应端点,其有效负载中包含可选加密的断言SAML。POST

    注意

    Amazon Cognito 会取消在 5 分钟内未收到响应的会话,并将用户重定向到托管用户界面。当您的用户遇到此结果时,他们会收到一条Something went wrong错误消息。

  6. 在验证SAML断言并映射响应中声明中的用户属性后,Amazon Cognito 会在内部创建或更新用户池中的用户个人资料。通常,您的用户池会向用户的浏览器会话返回授权码。

  7. 您的用户向您的应用程序出示他们的授权码,您的应用程序会将该代码兑换为JSON网络令牌(JWTs)。

  8. 您的应用程序接受并处理用户的 ID 令牌作为身份验证,使用其访问令牌生成对资源的授权请求,并存储他们的刷新令牌。

当用户进行身份验证并收到授权码授予时,用户池会返回 ID、访问和刷新令牌。ID 令牌是用于OIDC基于身份管理的身份验证对象。访问令牌是一个范围为 OAuth2.0 的授权对象。刷新令牌是一个在用户当前令牌过期时生成新 ID 和访问令牌的对象。您可以在用户池应用程序客户端中配置用户令牌的持续时间。

您也可以选择刷新令牌的持续时间。用户的刷新令牌到期后,他们必须重新登录。如果他们通过 SAML IdP 进行身份验证,则您的用户的会话持续时间由其令牌到期而不是他们与 IdP 的会话到期时间来设置。您的应用程序必须存储每位用户的刷新令牌,并在刷新令牌到期时续订他们的会话。托管用户界面在有效期为 1 小时的浏览器 Cookie 中维护用户会话。

使用 IDP 发起的登录 SAML

当您为 IDP 发起的 SAML 2.0 登录配置身份提供商时,您可以向用户池域中的saml2/idpresponse终端节点提供SAML断言,而无需在上启动会话。对端点授权具有此配置的用户池接受请求的应用程序客户端支持的用户池外部身份提供商发出的由 IDP 发起的SAML断言。以下步骤描述了 IdP 启动的 SAML 2.0 提供商配置和登录的整个过程。

  1. 创建或指定用户池和应用程序客户端。

  2. 在您的用户池中创建一个 SAML 2.0 IdP。

  3. 将您的 IdP 配置为支持 IdP 启动。IDP 启动SAML引入了其他SSO提供商不受制于的安全注意事项。因此,您不能向任何使用由 IDP 发起登录的SAML提供商的应用程序客户端添加非-SAML IdPs(包括用户池本身)。

  4. 将您的 IDP 发起的SAML提供商与用户池中的应用程序客户端相关联。

  5. 将您的用户引导到您的 Id SAML P 的登录页面并检索SAML断言。

  6. 使用他们的SAML断言将您的用户引导到您的用户池saml2/idpresponse终端节点。

  7. 接收JSON网络代币 (JWTs)。

要接受用户池中未经请求的SAML断言,必须考虑其对应用程序安全的影响。当您接受 IDP 发起的请求时,可能会出现请求欺骗和CSRF尝试。尽管您的用户池无法验证 IDP 发起的登录会话,但 Amazon Cognito 会验证您的请求参数和断言。SAML

此外,您的SAML索赔不得包含InResponseTo索赔,并且必须在过去 6 分钟内发出。

您必须向 IdP 发起的请求提交SAML给您。/saml2/idpresponse对于 SP 发起和托管的 UI 授权请求,您必须提供参数,将您请求的应用程序客户端、范围URI、重定向和其他详细信息标识为请求中的HTTP GET查询字符串参数。但是,对于 IDP 发起的SAML断言,请求的详细信息必须格式化为请求正文中的RelayState参数。HTTP POST请求正文还必须包含您的SAML断言作为SAMLResponse参数。

以下是 IdP 发起SAML的提供商的请求示例。

POST /saml2/idpresponse HTTP/1.1 User-Agent: USER_AGENT Accept: */* Host: example.auth.us-east-1.amazoncognito.com Content-Type: application/x-www-form-urlencoded SAMLResponse=[Base64-encoded SAML assertion]&RelayState=identity_provider%3DMySAMLIdP%26client_id%3D1example23456789%26redirect_uri%3Dhttps%3A%2F%2Fwww.example.com%26response_type%3Dcode%26scope%3Demail%2Bopenid%2Bphone HTTP/1.1 302 Found Date: Wed, 06 Dec 2023 00:15:29 GMT Content-Length: 0 x-amz-cognito-request-id: 8aba6eb5-fb54-4bc6-9368-c3878434f0fb Location: https://www.example.com?code=[Authorization code]
AWS Management Console
为 IdP 启动配置 IdP SAML
  1. 创建用户池应用程序客户端和SAML身份提供商。

  2. 取消所有社交和OIDC身份提供商与您的应用程序客户端的关联(如果有)。

  3. 导航到用户池的 “登录体验” 选项卡。

  4. 在 “联邦身份提供商登录” 下,编辑或添加提供SAML商。

  5. IDP 发起的SAML登录下,选择接受 SP 发起的和 IdP 发起的断言。SAML

  6. 选择 Save changes(保存更改)

API/CLI

为 IdP 启动配置 IdP SAML

使用CreateIdentityProviderUpdateIdentityProviderAPI请求中的IDPInit参数配置 IdP 启动SAML的。以下是支持 IdP ProviderDetails 启动的 IdP 的示例。SAML

"ProviderDetails": { "MetadataURL" : "https://myidp.example.com/saml/metadata", "IDPSignout" : "true", "RequestSigningAlgorithm" : "rsa-sha256", "EncryptedResponses" : "true", "IDPInit" : "true" }