5

我正在尝试了解如何使用 AWS mobilehub 的 iOS SDK 以开发人员身份验证身份登录,因为最近 AWS 更改了此 SDK,但我找不到任何相关文档。示例应用程序未能阐明这一点。

我有一个 REST API 来检索 cognito ID 和 Token 但我不知道一旦我有了这个该怎么处理它们。

AWS 有以下不同的类别,使问题进一步复杂化:

AWSCredentialsProvider、AWSCognitoCredentialsProvider(新开发工具包中不再提供)、AWSSignInProvider、AWSAbstractCognitoIdentityProvider(新开发工具包中不再提供)

现在有一个叫做 AWSAbstractCognitoIdentityProviderHelper..

这些由 AWSIdentityManager 处理,它是 AWSMobileHubHelper.framework 的一部分,但是 AWSIdentityManager 不允许您设置凭证提供程序,所以我不明白在这方面我应该如何与之交互。

任何教程、文档等将不胜感激

4

1 回答 1

30

您的问题暴露了某些术语问题:

  • 当您说开发人员时,我不确定您的意思与 AWS 的意思相同。
    • AWS 使用术语“开发者”(如“开发者身份”)来表示
      外部维护的池,而不是私人维护的池。AWS 拥有自己的产品(Cognito 用户池),您可以将其作为 AWS 服务私下维护。AWS 不将用户池视为开发人员身份提供商(但实际上,它只是开发人员身份提供商的完全实施重命名版本)。
  • 关于维护令牌
    • iOS 开发工具包维护您访问 AWSServices 所需的令牌。您应该使用 Mobile Hub,(它具有比 SDK 更好的对象和界面设计)。但无论您是直接使用 mobile-hub-helper 还是 SDK,您都无需管理令牌(SDK 会为您完成)。文档(几乎是残酷地)掩盖了这一事实(是的,它落后于 SDK)。

使用 Cognito 的 3 种方法

您必须了解有 3 种不同的接口 api。

  1. COGNITO API 和最新的API 文档(RESTFUL 交互)
  2. iOS SDK 和过时的SDK 文档(SDK 不是 RESTFUL,它有很多状态)。
  3. Mobile Hub Helper (MHH) SDK - MHH 由集线器记录(一点),并且在用于生成 appledoc 文档的 .h 文件中非常好。

关于身份和登录/身份验证(此问题的主题),aws-mobile-hub-helper(以下简称 MHH)具有优雅的设计并且运行良好。我建议任何使用 Cognito 的人从 Mobile Hub 站点开始(或至少从 aws-mobile-hub-helper 开始)。MHH 基本上是 SDK 的包装器,有助于澄清和分离AWS 服务的持久联合身份和凭证/授权问题与身份、身份验证和属性/声明的问题。

  • MHH 中的身份只有 1 个类AWSIdentityManager
  • MHH 中的 SignIn 有一个协议AWSSignInProvider和该协议的两个实现(加上我制作的一个):
    1. AWSGoogleSignInProvider : 适用于 Google+ 的 AWSSignInProvider 的 OpenID-Connect/OAuth 实施
    2. AWSFacebookSignInProvider:适用于 Facebook 的 AWSSignInProvider 的 OAuth/专有实施
    3. AWSCUPIdPSignInProvider:AWSSignInProvider 的 OpenID-Connect/OAuth 实施,用于 Amazon AWS Cognito 您的用户池服务(可在分叉存储库中获得)

mobile-hub-helper 仅记录在 .h 文件中。这些可以由 appledocs 处理成文档,如果您对类结构有一个概述(不存在,但我会尝试提供),那里的评论会非常好。

SDK 认证流程

AWS 记录的身份验证流程过于简单化,无助于理解如何使用 SDK 和 Mobile Hub Helper 完成身份验证。下图试图传达身份验证(登录)和授权(凭证)以使用 AWS 服务(如 S3 和 DynamoDB)的工作原理。

Cognito SDK 身份验证流程(单一身份提供者) Cognito SDK 身份验证流程(多个身份提供者)

了解认知

  • 理解 Cognito 最初由于多种
    原因而令人困惑:分布式系统中的身份验证、授权和身份管理
    很复杂。有许多具有不同角色的各方,并与密钥、令牌和
    签名进行详细的规定交互。最终用户、依赖方 (RP)、身份
    提供者 (IdP)、正在使用的资源 (RS) 和资源所有者
    (RO)。
    OpenId Connect 和 OAuth2.0标准文档使用此术语。出于将变得清楚的原因,
    AWS 并未始终使用此术语。但是在使用 Cognito 时,它们的概念和
    实体都在那里。
  • Cognito 允许非 OpenID Connect 身份提供者,这是一个优势(例如:允许 OAuth/专有 Facebook 身份 API),但这也意味着 Cognito 正在扮演“联合”<br>角色。这个角色超出了 OpenID Connect 标准
    文档的范围(更新 1:最近我开始怀疑 Cognito 凭证提供者是否真的是 RP(依赖方),然后它为 AWS 服务颁发凭证。但这里的重点是 OpenId Connect 并没有规定可以组合来自不同 IdP 的身份的方式。),亚马逊本质上是在发明这个角色,并且在这样做时遇到了一些命名挑战。

认知命名

  • Cognito 是 AWS 创建的一个单一名称,用于涵盖许多功能和角色。

    1. Cognito 有 RESTFUL Web API,但也有
      Cognito SDK。SDK 调用和 API 消息的名称
      不同,SDK 调用会进行多次和有条件的 API 调用。
    2. Cognito 可以联合身份提供者。它可以在来自不同身份提供商的经过身份验证的用户之间保持和
      关联
      (因此它可以记住您的 google+ 和您的 facebook
      身份并将它们与单个 Cognito 身份标识相关联。)
    3. Cognito 可以为用户和经过身份验证的用户提供持久的 identityId(如果是匿名的,则使用钥匙串数据跟随 iOS 设备)。这些存储在所谓的身份池中(不要与用户池混淆)。对于经过身份验证的用户,您的应用会在不同设备上为用户接收相同的 identityId。未经身份验证的(访客)身份标识跟随单个设备。
    4. Cognito 可以存储(称为“同步”)状态数据 IdentityId(在 AWS 服务器上),适用于经过身份验证和未经身份验证的用户。
    5. Cognito 有一个 AWSCredentialsProvider(用于使用 AWS 服务的 AWS 凭证的来源(Cognito 以及 S3、DynamoDB 等)
    6. Cognito 可以创建一个称为用户池的 OpenID Connect 服务器,Cognito Identity 可以使用该服务器对用户进行身份验证。
    7. Cognito 是新的,但 AWS Federated Identities 和 AWS Identity Management 和 AWS Credentials 不是,因此有很多职责重叠的类。并且命名约定令人困惑(考虑名称 AWSCognitoIdentityCognitoIdentityProvider!)。对用户池使用“cognito”品牌名称,真的是一场噩梦。AWSCognitoIdentity 事物是 Cognito 联合身份 CFI,但 AWSCognitoIdentityProvider 事物类似于用户池、身份验证提供者,也称为身份提供者。
  • SDK 类名称令人困惑。但除了少数例外,以AWSCognitoIdentity(但不是 AWSCognitoIdentityProvider)开头的类与 credentialsProvider/IdentityProvider 有关,以AWSCognitoIdentityProvider开头的类与 Oauth/Open Id Connect 提供商和其他分布式身份提供商 (facebook) 相关。

词汇表/同义词

这些术语在整个 AWS 文档和营销材料中被广泛使用。这是通过对 AWS 可互换使用的术语进行分组来整理术语的尝试。

  • 身份提供者、身份验证提供者、登录提供者、联合身份提供者
  • Amazon Cognito、Cognito 凭证提供商、cognito 身份(似乎都指同一个类/进程)
  • Cognito 用户池、Cognito 您的用户池、用户池。CUP身份提供者,又名身份验证提供者
  • Cognito 身份池,池,cognito 池,身份池。偶尔称为身份提供者(这似乎不正确),但从不称为身份验证提供者
  • 开发者身份、开发者认证身份、开发者提供者、开发者身份提供者,都用于指代私有的外部身份提供者。
  • 身份是 Cognito 文档中经常误用的术语。重要的是要了解 Cognito 管理两种不同的身份。identityId(应该是小写的)是 Cognito 与凭证关联并用于联合不同身份提供者的持久唯一名称,而 Identity(大写)是来自身份提供者的经过身份验证的标识符。
  • identityId身份ID,id(如get-id),identity,identityId
  • 身份
  • 联邦意味着很多东西。
  • Web 身份联合 - 在 AWS 联合身份的早期方式
  • Cognito 联合身份
  • BYOI(带上您自己的身份),用户通常可以通过 OpenId-Connect 使用 google、facebook 或其他身份提供者(可能是开发人员提供的身份)。

身份标识行为

  • 身份 id 看起来像这样:us-east-1:982396fs-841e-3cdd-9r43-e7ac41bhbcb28
  • identityId 在 iOS 设备上的钥匙串条目中维护。对于未经身份验证的 IdentityId,它保持不变,直到您清除钥匙串(这可以通过模拟器在模拟器中完成 -> 重置内容和设置...)。此时,IdentityId 被放弃。它没有被禁用,只是再也不会被使用。
  • 当用户进行身份验证时,身份验证会禁用当前在设备上的未经身份验证的 identityId(identityId 将在 identityPool 条目的 Logins 数组中永久标记为 DISABLED。您可以在 Cognito 控制台中看到这一点。)。有一个例外:如果这是第一次对此身份进行身份验证,则未验证的身份 ID 不会被放弃,而是与身份相关联并用作经过身份验证的身份 ID。

  • 合并来自不同身份提供者的多个身份(意味着用户名不是 IdentityId)会放弃(禁用)其中一个身份 ID,并将两个身份与另一个身份 ID 相关联。每当发生这种情况时,都会创建禁用 ID。在 cognito identityPool 的 Logins 数组中,这些废弃的 identityId 被标记为 DISABLED。

  • 在实践中,这个过程会合理使用唯一的identityId,只有在用户在新设备上进行身份验证时才会创建禁用的identityId(这在测试中可能会很麻烦,因为它会在测试人员注销和多次登录时创建大量禁用和未使用的identityId具有多个 id 的时间)。但在实践中,常见用例不会产生这种禁用身份标识的弹幕。用户会:

  • 连接 - 获取未经身份验证的 ID - 验证 - 并使用相同的 ID。没有创建废弃的 id。

  • 在另一台设备上连接——他/她会暂时获得一个新的未经身份验证的 id——当他/她通过身份验证并获得他/她的身份的 identityId 时,该未经身份验证的 id 将被禁用并放弃。
  • 来自两个身份提供者的身份的每次合并也会创建一个禁用和废弃的身份标识。

AWSIdentityProviderManager

  • AWSIdentityProviderManager 是管理联合 AWSIdentityProviders 的协议

  • 在 mobile-hub-helper AWSIdentityManager 是 AWSIdentityProviderManager

    • 它需要做的就是向凭证提供者返回一个登录字典,其中包含提供者名称和 ID 令牌。AWSIdentityManager 仅返回单个身份提供者的提供者名称和令牌。它只是从 AWSSignInProvider 获取名称和令牌并返回。(有一个带有修改的分支,增加了在登录字典中返回所有当前登录的提供程序的能力。)

    • 修改后的 AWSIdentityManager 维护一个名为 cachedLogins 的 NSDictionary。每个新登录都会将登录(身份提供者名称和 id 令牌)添加到缓存中。然后 logins 总是返回整个 loginCache。这就是支持身份合并的原因。

  • 当凭证提供者调用它关联的 AWSIdentityProviderManager 登录方法并找到登录列表而不是一个登录列表时,它将在其数据库中合并这些登录的 identityId 并禁用其中一个的 identityId。它如何知道哪个 ID 与哪个登录名对应?ID 令牌包含一组编码的可解密(将令牌粘贴到https://jwt.io以亲自查看)声明集,其中一个是身份(例如:用户名)

  • 注意:即使您的 identityId 具有多个相关登录名,但在 Mobile Hub Helper 中,您只能通过一个 AWSSignInProvider 进行身份验证。凭证与合并后的 identityId 相关联,但在 mobile-hub-helper 中,即使您使用多个身份提供者登录,也始终通过活动的 AWSSignInProvider(身份验证提供者)访问该 identityId。您的应用程序可以跟踪所有 AWSSignInProviders 并独立于 AWSIdentityManager 访问它们,但从 AWSIdentityManagers 的角度来看,您使用其中之一登录。在实践中,这几乎没有影响(直到您尝试从不同的提供商那里获得像 imageURL 这样的“声明”)。

关于合并身份

Cognito 埋藏数据的地方

  • Cognito 将钥匙串存储在设备上,其中包含上次使用的 identityId。在调用 credentialsProvider.credentials(iOS SDK 名称)时,credentialsProvider/identityProvider 对象使用它来重新使用现有身份(例如未经身份验证)并避免创建未使用的身份,除非用户确实不打算登录或恢复.

  • Mobile-Hub-Helper 的 AWSSignInProvider 和 AWSIdentityManager 将打开会话状态的指示存储在 NSUserDefaults 中。如果应用程序终止并重新启动,这些用于重新启动会话。

  • AWSSignInProvider 也存储 NSUserDefaults,有时在 iOS 钥匙串中,用于它们自己的内部目的(例如保持对用户名或 imageURL 或令牌的简单持久访问)

于 2016-10-26T16:57:58.040 回答