首页 > 解决方案 > 使用 Apple Security 登录关联帐户

问题描述

假设您在 Web 平台上有一个现有的用户管理/数据库。应该集成使用 Apple 登录,以便更快地登录和注册过程——尽管它总是会创建一个链接到电子邮件地址的常规帐户(只是没有常规密码)。使用 Apple 提供的(经过验证的)JWT 进行身份验证是否安全?

登录(现有帐户)将是以下步骤:

标签: securityjwtsign-in-with-apple

解决方案


我尝试为 iOS 应用程序设计一个答案。但首先要澄清问题:

“使用 Apple 提供的(经过验证的)JWT 进行身份验证是否安全?”

我们从授权任务中收到的唯一已知 JWT 是“id_token”。其他参数也可能是 JWT,但这些对客户端来说是不透明的。

现在的问题是,如果我们将 id_token 发送到应用服务器,仅验证 id_token 以向客户端分发应用服务器域的访问令牌就足够了吗?回答:不!

当使用 Apple 的 iOS 身份验证框架进行 Apple 登录时,授权任务ASAuthorization会在完成处理程序中返回一个值。这基本上包含以下参数:

  • user: 标识符
  • identityToken:JWT 的“id_token”(参见 OIDC)
  • authorizationCode:一种短暂的一次性有效令牌,可为应用程序的服务器组件提供授权证明。授权码使用授权请求中传递的状态属性绑定到特定交易。应用程序的服务器组件可以使用为此目的提供的 Apple 身份服务端点来验证代码。*)

*) 如果该值确实对应于客户端通过“前端通道”又名用户代理又名浏览器获得的 OIDC“代码”值,那么我们还应该确保有一个额外的机制,它实际上提供了一个安全的“授权证明”(Universal Links,PKCE),请参阅授权码拦截攻击。如果这些攻击在技术上是不可能的,因为身份验证系统提供了与应用程序的安全通信通道,但我们不需要 PKCE。

id_token 包含有关已通过身份验证的用户的信息,这些信息存储在 Provider 上。这是一个签名的 JWT。即使可以成功验证JWT,仅使用 JWT,应用服务器也无法确定发送者就是它认为的那个人。我们不想给任何未经身份验证的访问令牌!

应用服务器需要更多证明,这将通过authorizationCode参数来完成。但是,必须在 Provider 上进行此检查。

所以,我们必须执行两个步骤

  1. 验证身份令牌 (id_token) 这将在应用服务器上执行。

  2. 验证授权码

第二步将通过您的应用服务器从 Providers 特殊端点获取刷新令牌来完成。

在第 2 步中,我们收到一个TokenResponse

如果这成功了,我们会收到一个访问令牌和一个刷新令牌。访问令牌没有用,但我们需要刷新令牌:

“您最多可以每天验证一次刷新令牌,以确认该设备上用户的 Apple ID 在 Apple 服务器上的信誉良好。”

将其存储在您的应用服务器上。

在您的应用服务器上完成这一切后,您将继续:

管理用户会话

验证身份令牌后,您的应用程序负责管理用户会话。您可以将会话的生命周期与 Apple 设备上成功的 getCredentialState(forUserID:completion:) 调用联系起来。这是一个本地、廉价、非网络呼叫,由 Apple ID 系统启用,该系统使设备上的 Apple ID 状态与 Apple 服务器保持同步。

“用户会话”可能需要特定于域的访问令牌和刷新令牌。当客户端在您的令牌端点上需要新的访问令牌时,您可能会再次验证 Apple 的刷新令牌。

因此,最后一步是您的应用程序向您的客户端发送特定于域的访问令牌和刷新令牌。


推荐阅读