API 和 SDK 身份验证的授权模型
在开发支持用户池身份验证的应用程序之初,您必须根据您的应用程序类型选择合适的 API 授权模型。授权模型是一个用于对 Amazon Cognito 用户池 API 及 SDK 集成中的身份验证组件进行请求授权的系统。Amazon Cognito 提供三种授权模型:IAM 授权、公共访问和令牌授权。
在 IAM 授权的请求中,授权来自请求的 Authorization 标头中由一组 Amazon IAM 凭证生成的签名。对于服务器端应用程序,这种做法通过 IAM 授权来保护身份验证操作。而在公共(未经身份验证的)身份验证请求中,则无需任何授权。这种方式适用于分发给用户的客户端应用程序。令牌授权的操作通常与公共操作结合使用,授权来自于请求的 Authorization 标头中包含的会话令牌或访问令牌。Amazon Cognito 身份验证通常要求您按顺序实现两个或更多 API 操作,而具体使用哪些 API 操作则取决于您的应用程序特性。公共客户端(应用程序分发给用户时使用)采用的是公共操作,也就是说,用户发起登录请求时,不需要获得授权。令牌授权操作用于在公共应用程序中延续用户的会话。而服务器端客户端(其中,应用程序逻辑托管在远程系统上)则通过对登录请求的 IAM 授权来保护身份验证操作。以下 API 操作组合及其对应的 SDK 方法,分别对应可用的多种授权模型。
每个公共身份验证操作通常都有对应的服务器端等效操作,例如 UpdateUserAttributes 和 AdminUpdateUserAttributes。客户端操作由用户发起,通常需要用户确认,而服务器端操作则假定更改是由用户池管理员提交的,因此更改会立即生效。在本例中,Amazon Cognito 会向用户发送一条包含确认码的消息,用户使用其访问令牌授权一个 VerifyUserAttribute 请求,以提交该确认码。而服务器端应用程序则可以立即设置任意属性的值,但在更改用于登录的电子邮件地址或电话号码时,需遵循特殊规则。
要比较 API 身份验证并查看 API 操作及其授权模型的完整列表,请参阅了解 API、OIDC 和托管登录页面身份验证。
用户通过应答连续的质询进行身份验证,直到身份验证失败或 Amazon Cognito 向用户颁发令牌。您可以在包含不同质询的流程中对 Amazon Cognito 重复这些步骤,以支持任何自定义身份验证流程。
服务器端身份验证选项
Web 应用程序及其他服务器端 应用程序在远程服务器上实现身份验证,客户端通过浏览器或 SSH 会话等远程显示应用程序加载这些服务器。服务器端应用程序通常具有以下特征。
通过用户池 API 执行的服务器端操作可以使用密码、一次性密码或通行密钥作为主要的登录因素。对于服务器端应用程序,用户池身份验证与客户端应用程序的身份验证类似,但以下情况除外:
-
服务器端应用程序发出一个 AdminInitiateAuth API 请求。此操作需要 Amazon 凭证,此凭证拥有的权限包括
cognito-idp:AdminInitiateAuth和cognito-idp:AdminRespondToAuthChallenge。该操作返回必需的质询或身份验证结果。 -
当应用程序收到质询时,会发出一个 AdminRespondToAuthChallenge API 请求。此
AdminRespondToAuthChallengeAPI 操作也需要 Amazon 凭证。
有关使用 Amazon 凭证对 Amazon Cognito API 请求签名的更多信息,请参阅 Amazon 一般参考 中的签名版本 4 签名过程。
在 AdminInitiateAuth 响应 ChallengeParameters 中,USER_ID_FOR_SRP 属性(如果存在)包含用户的实际用户名而不是别名(如电子邮件地址或电话号码)。在 AdminRespondToAuthChallenge 调用的 ChallengeResponses 中,您必须在 USERNAME 参数中传递此用户名。
注意
由于后端管理员实施使用管理员身份验证流程,该流程不支持“记住的设备”功能。在您启用设备跟踪时,管理员身份验证成功,但任何对刷新访问令牌的调用均会失败。
客户端身份验证选项
移动应用程序及其他客户端 应用程序类型安装在用户的设备上,并在本地执行身份验证逻辑和用户界面的逻辑。它们通常具有以下特征。
通过用户池 API 执行的客户端操作可以使用密码、一次性密码或通行密钥作为主要的登录因素。以下过程适用于您使用 Amazon Amplify
-
用户将他们的用户名和密码输入到应用程序中。
-
应用程序使用用户的用户名和安全远程密码(SRP)详细信息调用
InitiateAuth操作。此 API 操作返回身份验证参数。
注意
该应用程序使用 Amazon 开发工具包内置的 Amazon Cognito SRP 特征生成 SRP 详细信息。
-
应用程序调用
RespondToAuthChallenge操作。如果调用成功,则 Amazon Cognito 返回用户的令牌,并且身份验证流程完成。如果 Amazon Cognito 需要另一个质询,则对
RespondToAuthChallenge的调用不返回任何令牌。相反,调用会返回一个会话。 -
如果
RespondToAuthChallenge返回一个会话,应用程序将再次调用RespondToAuthChallenge,这次使用会话和质询响应(例如,MFA 代码)。
了解 API、OIDC 和托管登录页面身份验证
Amazon Cognito 用户池是多种身份验证技术的组合。它们是外部身份提供者(IdP)的依赖方,也是使用 OpenID Connect(OIDC)SDK 实现身份验证的应用程序的 IdP。它们作为 JSON Web Token(JWT)的颁发者提供身份验证,类似于 OIDC 身份验证,但通过 Amazon SDK 中的 API 方法实现。它们也可以作为您应用程序的安全入口点。
当您想要注册、登录和管理用户池中的用户时,有两种选择。
-
您的托管登录页面 和经典托管 UI 包括托管登录用户交互式端点以及处理 IdP 和依赖方角色的联合端点。它们构成了一个公开网页包,当您为用户池选择域时,Amazon Cognito 会激活这些网页。要快速开始使用 Amazon Cognito 用户池的身份验证和授权功能,包括注册、登录、密码管理和多重身份验证(MFA)页面,请使用托管登录的内置用户界面。
其他用户池端点便于使用第三方身份提供者(IdP)进行身份验证。他们执行的服务包括以下各项。
-
服务提供者回调端点,用于处理来自您的 IdP 的经身份验证的声明,例如
saml2/idpresponse和oauth2/idpresponse。当 Amazon Cognito 是您的应用程序和 IdP 之间的中间服务提供者(SP)时,回调端点代表服务。 -
提供有关您的环境的信息的端点,例如
oauth2/userInfo和/.well-known/jwks.json。您的应用程序在使用 OIDC 或 OAuth 2.0 开发人员库验证令牌或检索用户配置文件数据时使用这些端点。
-
-
Amazon Cognito 用户池 API 是一组用于您的 Web 或移动应用程序的工具,用于在您自己的自定义前端中收集登录信息之后验证用户身份。用户池 API 身份验证生成以下 JSON Web 令牌。
-
带有来自您的用户的可验证属性声明的身份令牌。
-
一种访问令牌,用于授权用户针对 Amazon 服务端点创建经令牌授权的 API 请求。
注意
默认情况下,来自用户池 API 身份验证的访问令牌仅包含
aws.cognito.signin.user.admin作用域。要生成具有额外作用域的访问令牌(例如,授权对第三方 API 的请求),请在通过用户池端点进行身份验证期间请求作用域,或者在 令牌生成前 Lambda 触发器 中添加自定义作用域。自定义访问令牌会增加您的 Amazon 账单费用。 -
一种刷新令牌,用于授权请求新 ID 令牌和访问令牌,并刷新用户身份和访问控制属性。
-
您可以将通常通过用户池端点登录的联合用户与其配置文件位于用户池本地 的用户相关联。本地用户仅存在于您的用户池目录中,无需通过外部 IdP 进行联合身份验证。如果您在 AdminLinkProviderForUser API 请求中将他们的联合身份链接到本地用户,则他们可以使用用户池 API 进行登录。有关更多信息,请参阅将联合用户与现有用户配置文件关联。
Amazon Cognito 用户池 API 有双重用途。
-
它创建和配置您的 Amazon Cognito 用户池资源。例如,您可以创建用户池、添加 Amazon Lambda 触发器以及配置托管您的托管登录页面的用户池域。
-
它还为本地用户和关联的用户执行注册、登录和其他用户操作。
使用 Amazon Cognito 用户池 API 的示例场景
-
用户选择了您在应用程序中创建的“创建账户”按钮。他们输入电子邮件地址和密码。
-
您的应用程序发送了 SignUp API 请求,并在用户池中创建新用户。
-
应用程序提示用户输入电子邮件确认码。用户输入他们在电子邮件中收到的代码。
-
您的应用程序发送带有用户确认码的 ConfirmSignUp API 请求。
-
应用程序提示您的用户输入用户名和密码,而用户输入其信息。
-
您的应用程序发送 InitiateAuth API 请求并存储 ID 令牌、访问令牌和刷新令牌。应用程序调用 OIDC 库来管理用户的令牌并为该用户维护持久会话。
在 Amazon Cognito 用户池 API 中,您无法登录通过 IdP 进行联合身份验证的用户。您必须通过用户池端点对这些用户进行身份验证。有关包含托管登录的用户池端点的更多信息,请参阅用户池端点和托管登录参考。
联合用户可以在托管登录中开始登录并选择其 IdP,您也可以跳过托管登录,将用户直接发送到您的 IdP 以进行登录。当您的 API 发送请求到 对端点授权 且带有 IdP 参数时,Amazon Cognito 会以静默方式将用户重定向到 IdP 登录页面。
托管登录页面的场景示例
-
用户选择了您在应用程序中创建的“创建账户”按钮。
-
托管登录向用户提供您注册开发人员凭证使用的社交身份提供者列表。您的用户选择了 Apple。
-
您的应用程序向 对端点授权 发出请求,提供者名称为
SignInWithApple。 -
用户的浏览器打开 Apple 身份验证页面。用户登录,并选择授权 Amazon Cognito 读取其个人资料信息。
-
Amazon Cognito 确认 Apple 访问令牌并查询用户的 Apple 个人资料。
-
用户向您的应用程序出示 Amazon Cognito 授权码。
-
应用程序中的 OIDC 库与 令牌端点 交换授权码并存储用户池颁发的 ID 令牌、访问令牌和刷新令牌。应用程序使用 OIDC 库来管理用户的令牌并为该用户维护持久会话。
用户池 API 和托管登录页面支持多种应用场景,这些场景在本指南中均有说明。以下部分探讨了用户池 API 如何进一步划分为支持您的注册、登录和资源管理要求的类。
按授权模型分组的 API 操作列表
Amazon Cognito 用户池 API 既是资源管理接口,也是面向用户的身份验证和授权接口,结合了其操作中遵循的授权模型。根据 API 操作,您可能需要使用 IAM 凭证、访问令牌、会话令牌、客户端密钥或者前面这些内容的组合提供授权。对于许多用户身份验证和授权操作,您可以选择请求的经过身份验证和未经身份验证的版本。对于分发给用户的应用程序(例如移动应用程序),最佳安全实践是提供未经身份验证的操作;您无需在代码中包含任何密钥。
您只能在 IAM policy 中为 IAM 授权的管理操作 和 IAM 授权的用户操作 分配权限。
IAM 授权的管理操作会修改和查看您的用户池和应用程序客户端配置,就像您在 Amazon Web Services 管理控制台 中所做的那样。
例如,要在 UpdateUserPool API 请求中修改您的用户池,您必须提供 Amazon 凭证和 IAM 权限才能更新资源。
要在 Amazon Command Line Interface(Amazon CLI)或 Amazon SDK 中授权这些请求,请使用将 IAM 凭证添加到请求的环境变量或客户端配置来配置您的环境。有关更多信息,请参阅《Amazon Web Services 一般参考》中的使用 Amazon 凭证访问 Amazon。对于 Amazon Cognito 用户池 API,您也可以直接向服务端点发送请求。您必须使用嵌入到请求标头中的 Amazon 凭证授权或签署 这些请求。有关更多信息,请参阅签署 Amazon API 请求。
IAM 授权的用户操作注册、登录、管理凭证、修改和查看您的用户。
例如,您可以有一个服务器端应用程序层,为 Web 前端提供支持。您的服务器端应用程序是可以信任的 OAuth 机密客户端,具有对您 Amazon Cognito 资源的特权访问权限。要在应用程序中注册用户,您的服务器可以在 AdminCreateUser API 请求中包含 Amazon。有关 OAuth 客户端类型的更多信息,请参阅 OAuth 2.0 授权框架中的客户端类型
要在 Amazon CLI 或 Amazon SDK 中授权这些请求,请使用将 IAM 凭证添加到请求的环境变量或客户端配置来配置服务器端应用程序的环境。有关更多信息,请参阅《Amazon Web Services 一般参考》中的使用 Amazon 凭证访问 Amazon。对于 Amazon Cognito 用户池 API,您也可以直接向服务端点发送请求。您必须使用嵌入到请求标头中的 Amazon 凭证授权或签署 这些请求。有关更多信息,请参阅签署 Amazon API 请求。
如果您的应用程序客户端有客户端密钥,则您必须提供 IAM 凭证,并在 AuthParameters 中提供 SecretHash 参数或 SECRET_HASH 值(取决于操作)。有关更多信息,请参阅计算密钥哈希值。
未经身份验证的用户操作注册、登录以及为您的用户启动密码重置。当您希望 Internet 上的任何人都可以注册并登录您的应用程序时,请使用未经身份验证(公开)的 API 操作。
例如,要在您的应用程序中注册用户,您可以分发 OAuth 公共客户端,其中不提供对密钥的任何特权访问。您可以使用未经身份验证的 API 操作 SignUp 注册此用户。
要在使用 Amazon SDK 开发的公共客户端中发送这些请求,您无需配置任何凭证。对于没有额外授权的 Amazon Cognito 用户池 API,您也可以直接向服务端点发送请求。
如果您的应用程序客户端有客户端密钥,则您必须在 AuthParameters 中提供 SecretHash 参数或 SECRET_HASH 值(取决于操作)。有关更多信息,请参阅计算密钥哈希值。
经过令牌授权的用户操作在用户已登录或开始登录流程之后,注销、管理其凭证、修改和查看用户。如果您不想在应用程序中分发密钥,并且想要使用用户自己的凭证授权请求,请使用经过令牌授权的 API 操作。如果用户已完成登录,则您必须使用访问令牌来授权其经过令牌授权的 API 请求。如果您的用户正在登录流程中,则您必须使用 Amazon Cognito 在对先前请求的响应中返回的会话令牌,授权其经过令牌授权的 API 请求。
例如,在公共客户端中,您可能希望更新用户的配置文件,限制用户仅对自己的配置文件具有写入权限。要进行此更新,您的客户端可以在 UpdateUserAttributes API 请求中包含用户的访问令牌。
要在使用 Amazon SDK 开发的公共客户端中发送这些请求,您无需配置任何凭证。在您的请求中包含 AccessToken 或 Session 参数。对于 Amazon Cognito 用户池 API,您也可以直接向服务端点发送请求。要向服务端点授权请求,请在请求的 POST 正文中包含访问令牌或会话令牌。
要签署经过令牌授权的操作的 API 请求,请将访问令牌作为 Authorization 标头包含在请求中,格式为 Bearer
。<Base64-encoded access token>
¹ RevokeToken 和 GetTokensFromRefreshToken 将刷新令牌作为授权参数。刷新令牌用作授权令牌和目标资源。