本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon Cognito 用户池安全最佳实践
本页介绍了当你想防范常见威胁时可以实施的安全最佳实践。您选择的配置将取决于每个应用程序的用例。我们建议您至少对管理操作应用最低权限,并采取措施保护应用程序和用户密钥。您可以采取的另一个高级但有效的步骤是配置 Amazon WAF Web 并将其应用 ACLs 于您的用户池。
在网络层面保护您的用户池
Amazon WAF web ACLs 可以保护您使用 Amazon Cognito 构建的身份验证机制的性能和成本。借助 Web ACLs,您可以在 API 和托管登录请求之前设置防护栏。Web ACLs 创建网络层和应用层过滤器,这些过滤器可以根据您设计的规则丢弃流量或要求使用验证码。请求只有在满足您的 Web ACL 规则中的条件后才会传递到您的 Amazon Cognito 资源。有关更多信息,请参阅 Amazon WAF web ACLs。
防范短信滥用
如果您允许在用户池中进行公开注册,则可以使用 Amazon Cognito 在 SMS 短信中发送的代码来配置账户验证。SMS 消息可能与不想要的活动相关联,从而增加您的 Amazon 账单。配置您的基础架构,使其能够抵御在欺诈情况下发送 SMS 消息。有关更多信息,请查看 Amazon 博客中的以下帖子。
了解公共身份验证
Amazon Cognito 用户池具有客户身份和访问管理 (CIAM) 功能,这些功能支持公众可以注册用户账户并访问您的应用程序的用例。当用户池允许自助注册时,它可以接受来自公共互联网的用户帐户请求。自助服务请求来自和之类的 API 操作 InitiateAuth,SignUp以及用户与托管登录的交互。您可以配置用户池以减少可能来自公共请求的滥用行为,或者完全禁用公共身份验证操作。
以下设置是您可以在用户池和应用程序客户端中管理公共和内部身份验证请求的一些方法。
设置 | 可用选项 | 已配置于 | 对公共身份验证的影响 | 控制台设置 | API 操作和参数 |
---|---|---|---|---|---|
自助注册 | 允许用户以管理员身份注册帐户或创建用户帐户。 | 用户群体 | 阻止公开注册 | 注册-自助注册 |
CreateUserPool, UpdateUserPool
|
管理员确认 | 向新用户发送确认码或要求管理员进行确认。 | 用户群体 | 防止在没有管理员操作的情况下确认注册 | 注册 — Cognito 辅助的验证和确认 |
CreateUserPool, UpdateUserPool
|
用户披露 | 在登录和密码重置时发送 “未找到用户” 消息,或者防止泄露。 | 用户群体 | 防止猜测登录名、电子邮件地址或电话号码 | 应用程序客户端-防止用户存在错误 |
CreateUserPoolClient, UpdateUserPoolClient
|
客户端密钥 | 在注册、登录、密码重置时需要或不需要密钥哈希 | 应用程序客户端 | 防范来自未经授权来源的身份验证请求 | 应用程序客户端-客户端密钥 |
|
Web ACLs | 为身份验证请求启用或不启用网络防火墙 | 用户群体 | 根据管理员定义的请求特征和 IP 地址规则限制或阻止访问 | Amazon WAF— WAF 设置 |
|
外部 IdP | 允许用户在第三方 IdPs、用户池目录或两者中登录 | 应用程序客户端 | 将本地用户或联合用户排除在注册和登录之外。 | 应用程序客户端-身份提供商 |
CreateUserPoolClient, UpdateUserPoolClient
|
授权服务器 | 托管或不托管公共网页进行身份验证 | 用户群体 | 关闭公共网页,只允许基于 SDK 的身份验证 | 域 |
创建任何用户池域都会使公共网页可用。 |
威胁防护 | 启用或禁用对恶意活动迹象或不安全密码的监控 | 用户池或应用程序客户端 | 当用户显示泄露迹象时,可以自动阻止登录或要求 MFA | 威胁防护-防护设置 |
的参数 |
使用客户机密保护机密客户
客户端密钥是与应用程序客户端关联的可选字符串。向具有客户端密钥的应用程序客户端发出的所有身份验证请求都必须包含由用户名、客户端 ID 和客户端密钥生成的密钥哈希。那些不知道客户机密的人从一开始就被拒之门外。
但是,客户机密有局限性。如果您在公共客户端软件中嵌入了客户端密钥,则您的客户端密钥可以接受检查。这使您能够在应用程序客户端中创建用户、提交密码重置请求和执行其他操作。只有当应用程序是唯一有权访问该密钥的实体时,才必须实现客户端密钥。通常,这在服务器端机密客户端应用程序中是可能的。需要客户端密钥的 M2M 应用程序也是如此。将客户端密钥存储在加密的本地存储器中或 Amazon Secrets Manager。切勿让您的客户机密在公共互联网上可见。
保护其他机密
您使用 Amazon Cognito 用户池的身份验证系统可能会处理私有数据、密码和证书。 Amazon 以下是处理应用程序可能访问的密钥的一些最佳实践。
- 密码
-
用户在登录您的应用程序时可能会输入密码。Amazon Cognito 有刷新令牌,您的应用程序可以使用这些令牌在没有新密码提示的情况下继续使用过期的用户会话。不要在本地存储中放置任何密码或密码哈希。将您的应用程序设计为将密码视为不透明,并且仅将其传递到您的用户池。
最佳做法是使用密钥实现无密码身份验证。WebAuthn如果您必须使用密码,请使用安全远程密码 (SRP) 身份验证流程和多因素身份验证 (MFA)。
- Amazon 证书
-
管理身份验证和用户池管理操作需要使用 Amazon 凭据进行身份验证。要在应用程序中实现这些操作,请授予对临时 Amazon 证书的安全访问权限。仅向在您控制的服务器组件上运行的应用程序授予凭据访问权限。不要将包含 Amazon 凭据的应用程序放在公共版本控制系统上,例如。 GitHub不要在公共客户端应用程序中对 Amazon 凭据进行编码。
- PKCE 代码验证器
-
代码交换(PKCE)的证明密钥用于向您的用户池授权服务器授予 OpenID Connect (OIDC) 授权码。当应用程序请求授权码时,它们会与您的用户池共享代码验证器密钥。要将授权码换成令牌,客户必须重申他们知道代码验证器。这种做法可以防止发行带有被拦截的授权码的代币。
客户端必须为每个授权请求生成一个新的随机码验证器。使用静态或可预测的代码验证器意味着只有这样,攻击者才需要拦截硬编码的验证器和授权码。设计您的应用程序,使其不会向用户公开代码验证器值。
用户池管理最低权限
IAM 策略可以定义委托人对 Amazon Cognito 用户池管理和管理身份验证操作的访问级别。例如:
-
向 Web 服务器授予使用管理 API 操作进行身份验证的权限。
-
对于管理您的 Amazon IAM Identity Center 用户池的用户 Amazon Web Services 账户,请授予用户池维护和报告的权限。
出于IAM策略的目的,Amazon Cognito中的资源粒度级别仅限于两种资源类型:用户池和身份池。请注意,您不能应用权限来管理单个应用程序客户端。在配置用户池时要知道您授予的权限在所有应用程序客户端上均有效。如果您的组织有多个应用程序租户,并且您的安全模型要求租户之间的管理责任分开,则可以实现多租户,每个用户池只有一个租户。
尽管您可以创建具有用户身份验证操作权限的 IAM 策略InitiateAuth
,但这些权限无效。公开和令牌授权的 API 操作不受 IA M 权限的约束。在可用的用户池身份验证操作中,您只能向服务器端的管理操作授予权限,例如AdminInitiateAuth
。
您可以使用最低权限列表Action
来限制用户池的管理级别。以下示例策略适用于可以管理资源服务器 IdPs、应用程序客户端和用户池域的管理员,但不能管理用户或用户池。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "UserPoolClientAdministrator", "Action": [ "cognito-idp:CreateIdentityProvider", "cognito-idp:CreateManagedLoginBranding", "cognito-idp:CreateResourceServer", "cognito-idp:CreateUserPoolDomain", "cognito-idp:DeleteIdentityProvider", "cognito-idp:DeleteResourceServer", "cognito-idp:DeleteUserPoolDomain", "cognito-idp:DescribeIdentityProvider", "cognito-idp:DescribeManagedLoginBranding", "cognito-idp:DescribeManagedLoginBrandingByClient", "cognito-idp:DescribeResourceServer", "cognito-idp:DescribeUserPool", "cognito-idp:DescribeUserPoolClient", "cognito-idp:DescribeUserPoolDomain", "cognito-idp:GetIdentityProviderByIdentifier", "cognito-idp:GetUICustomization", "cognito-idp:ListIdentityProviders", "cognito-idp:ListResourceServers", "cognito-idp:ListUserPoolClients", "cognito-idp:ListUserPools", "cognito-idp:SetUICustomization", "cognito-idp:UpdateIdentityProvider", "cognito-idp:UpdateManagedLoginBranding", "cognito-idp:UpdateResourceServer", "cognito-idp:UpdateUserPoolClient", "cognito-idp:UpdateUserPoolDomain" ], "Effect": "Allow", "Resource": "arn:aws:cognito-idp:us-west-2:123456789012:userpool/us-west-2_EXAMPLE" } ] }
以下示例策略向服务器端应用程序授予用户和组的管理和身份验证。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "UserAdminAuthN", "Action": [ "cognito-idp:AdminAddUserToGroup", "cognito-idp:AdminConfirmSignUp", "cognito-idp:AdminCreateUser", "cognito-idp:AdminDeleteUser", "cognito-idp:AdminDeleteUserAttributes", "cognito-idp:AdminDisableProviderForUser", "cognito-idp:AdminDisableUser", "cognito-idp:AdminEnableUser", "cognito-idp:AdminForgetDevice", "cognito-idp:AdminGetDevice", "cognito-idp:AdminGetUser", "cognito-idp:AdminInitiateAuth", "cognito-idp:AdminLinkProviderForUser", "cognito-idp:AdminListDevices", "cognito-idp:AdminListGroupsForUser", "cognito-idp:AdminListUserAuthEvents", "cognito-idp:AdminRemoveUserFromGroup", "cognito-idp:AdminResetUserPassword", "cognito-idp:AdminRespondToAuthChallenge", "cognito-idp:AdminSetUserMFAPreference", "cognito-idp:AdminSetUserPassword", "cognito-idp:AdminSetUserSettings", "cognito-idp:AdminUpdateAuthEventFeedback", "cognito-idp:AdminUpdateDeviceStatus", "cognito-idp:AdminUpdateUserAttributes", "cognito-idp:AdminUserGlobalSignOut", "cognito-idp:AssociateSoftwareToken", "cognito-idp:ListGroups", "cognito-idp:ListUsers", "cognito-idp:ListUsersInGroup", "cognito-idp:RevokeToken", "cognito-idp:UpdateGroup", "cognito-idp:VerifySoftwareToken" ], "Effect": "Allow", "Resource": "arn:aws:cognito-idp:us-west-2:123456789012:userpool/us-west-2_EXAMPLE" } ] }
保护和验证令牌
令牌可以包含对群组成员资格的内部引用以及您可能不想向最终用户披露的用户属性。不要将 ID 和访问令牌存储在本地存储中。刷新令牌使用只有您的用户池才能访问的密钥进行加密,并且对用户和应用程序不透明。当用户注@@ 销或出于安全原因您认为不希望保留用户会话时,撤消刷新令牌。
使用访问令牌仅向独立验证令牌有效且未过期的系统授予访问权限。有关验证资源,请参阅验证 JSON 网络令牌。
确定您要信任的身份提供商
使用 SAML 或 OIDC 身份提供商 (IdPs) 配置用户池时, IdPs 您可以创建新用户、设置用户属性和访问您的应用程序资源。SAML 和 OIDC 提供商通常用于 business-to-business (B2B) 或企业场景,在这种场景中,您或您的直属客户控制提供商的成员资格和配置。
社交提供商向互联网上的任何人提供用户帐户,与企业提供商相比,您的控制更少。只有当你准备好允许公众客户登录和访问应用程序 IdPs 中的资源时,才能在应用程序客户端中激活 social。
了解范围对用户个人资料访问权限的影响
您可以在向用户池授权服务器的身份验证请求中请求访问控制范围。这些作用域可以授予您的用户访问外部资源的权限,也可以授予用户查看和修改自己的用户个人资料的权限。配置您的应用程序客户端,使其支持应用程序运行所需的最小范围。
该aws.cognito.signin.user.admin
作用域存在于 SDK 身份验证通过以下操作颁发的所有访问令牌中InitiateAuth。它专为应用程序中的用户配置文件自助服务操作而设计。您也可以向授权服务器请求此作用域。此作用域是令牌授权的操作(如和)所必需的。UpdateUserAttributesGetUser这些操作的效果受应用程序客户端的读取和写入权限的限制。
openid
、profile
email
、和phone
范围授权向您的用户池授权服务器userInfo 端点上的请求。它们定义端点可以返回的属性。如果请求时没有其他作用域,则作用域会返回所有可用属性,但是当您在请求中请求更多作用域时,响应范围会缩小到由其他作用域表示的属性。openid
openid
范围还表示对 ID 令牌的请求;当您在向您的请求中省略此范围时,Amazon Cognito 只会发出访问令牌,如果适用,还会发出刷新令牌。对端点授权有关更多信息,请参阅 OpenID Connect 作用域,网址为。应用程序客户端术语
清理用户属性的输入
例如email
,可能最终成为交付方法和用户名的用户属性有格式限制。其他属性可以有字符串、布尔值或数字数据类型。字符串属性值支持各种输入。配置您的应用程序,以防有人试图向您的用户目录写入不需要的数据或 Amazon Cognito 向用户发送的消息。在将应用程序中用户提交的字符串属性值提交给 Amazon Cognito 之前,对其进行客户端验证。
用户池根据您指定的属性映射将属性从映射 IdPs 到您的用户池。仅将安全且可预测的 IdP 属性映射到用户池字符串属性。