我应该将密码保存在共享网络凭据和(本地)钥匙串中吗?

12

我正在设计一个新应用的登录页面,该应用将与域名关联,即成为SPA的补充部分。显然我想使用:

  • iOS 11密码自动填充,并且
  • Shared Web Credentials

我已经阅读了有关自动填充的文档,并观看了有关此内容的WWDC视频。另外,我还查看了共享Web凭据的文章,我认为这篇文章比重新设计的自动填充要老。该文章建议:

不要将共享Web凭据用作安全用户凭据的主要存储。相反,请将用户的凭据保存在钥匙串中,并仅在找不到登录凭据时才使用共享Web凭据。

这让我有点奇怪,因为: - 这意味着我必须涵盖更多可能的不一致性,即以某种方式同步密钥串和共享Web凭据(如果我的keychain中有凭证以及共享Web凭据,但它们不同怎么办?) - 如果我的用户卸载我的应用程序,可能会在keychain中留下“垃圾”(自然地,我希望他们永远不会这样做,但让我们保持现实,有些人会这样做)

特别是最后一点总是困扰着我(在共享Web凭据和自动填充成为时尚之前,或者当我的应用程序没有关联的域时)。与macOS上不同,在设置应用中的iOS帐户和密码功能只列出Safari使用过的密码(即共享Web凭据),对吗?相比之下,macOS上的钥匙串访问提供了一种查看和管理所有凭据的方法,即使它们未通过iCloud同步也可以。

我理解为什么iOS上不能提供相同的功能,但这也意味着对于那些我的应用程序本地保存在“其”钥匙链“部分”的密码,只有在我在我的应用程序中提供UI时才能管理。如果用户在使用此功能之前卸载应用程序,则该项将保留在钥匙链中,至少在几年前我尝试时是这样。
我现在的主要问题是,是否可以更轻松地忽略文章的建议,仅依靠共享的Web凭据进行密码存储?那是他们可以在设置中编辑的部分(如果需要的话),并且它还会反映网站上进行的任何密码更改。然后我会像这样设计我的应用程序:
- 首次启动:应用程序从自动填充方式开始在登录屏幕上提供用户名/密码。 - 用户登录:应用程序将一个简单的标志保存在共享用户默认值中,表示已登录用户。 - 应用程序重新启动(例如,在设备重启后):由于标记,应用程序跳过登录屏幕,并从共享Web凭据获取密码和用户名(当然假设用户先前授权了它)。 - 用户明确注销:应用程序删除标志,基本上将一切恢复到首次启动 - 用户从共享Web凭据中删除用户名和密码(例如在macOS上使用设置应用程序或Keychain Access):应用程序在检测到此时回退到登录屏幕(例如在远程请求后或重新启动后),无论标志如何。我认为这最符合用户意图(如果您删除密码,您不希望某些应用程序一直持有它,直到您将其注销)
这种设置可以避免钥匙链和共享Web存储中的任何不同项问题,并且还可以立即将网页上进行的更新传播到应用程序中(这正是我对我的应用程序的意图)。是否有任何会阻止此应用程序流程工作的内容?非常感谢您提供的信息。您的答案帮助我意识到我对共享Web凭据的理解存在误解:我假设对于与域名关联的应用程序,您可以在没有用户交互的情况下(可能是初始授权后)访问凭据。就像在macOS上当应用程序请求凭据时,您可以设置复选框一样。我现在意识到这是错误的,在iOS上,您始终需要与用户验证,谢谢。
为了完整起见,我仍然想指出您说的其他一些事情:
- 您是正确的,我们最终将使用基于令牌的身份验证,因此我将在钥匙串中保存它(可能还要保存密码,请参见下文)。我只是试图首先将问题简单化。 - 我们的应用程序类似于电子邮件客户端,您可以更新新收到的“邮件”。提到的“登录标志”就像用户默认值中的内容一样,因此只需表示该应用程序是否应该表现得好像已订阅收件箱或者未订阅。就像在Mail中一样,您不希望即使在重新启动后也必须登录。 - 出于这个原因,我可能最终会将用户的密码保存在(本地的)钥匙串中,并附带一个令牌。如果令牌过期,我可以在没有用户交互的情况下请求新令牌,这在我们的通用站点和应用程序设计中非常重要。只有在该请求失败时,我才会使用共享的Web凭据(在此过程中更新我的凭据本地副本)。 - 就您提到的最后一点而言,这可能是有争议的。例如,在macOS上(在那里您可以编辑整个钥匙串,而不仅仅是Safari密码),实际上登出了一个应用程序。再次以Mail为例。如果收件箱的钥匙串项目消失了,Mail将在下次启动并尝试访问内容时重新询问(实际上是一种“登录”方式)。
再次感谢您的回答,现在我可以关闭一个未完成的任务。 :) 同时感谢@HamZa提供悬赏!

我会说这个问题相当有趣,但它是基于观点的。对于普通用户来说,通过这种机制管理保存的密码并不容易。在我看来,我认为这种机制非常适合用户使用。如果我是您,我会按照文章的建议作为最佳实践,但一定要向用户解释如何管理他们保存的凭据。 - Raptor
谢谢您的评论。关于我勾画的应用程序流程是否最佳,这是基于意见的。但实际的核心问题是,出于技术原因(共享网络凭据不可靠、缓存、权限等),您是否需要在(应用程序的)钥匙串中保存凭据。此外,我不确定您指的机制是哪一个很好,是我提出的还是文章中解释的那个。请注意,后者没有提到如何管理(钥匙串)密码。大多数应用程序根本不会管理它,卸载时留下垃圾。用户没有意识到,但我认为这并不优秀。 :) - Gero
你在应用程序开发论坛上是否收到了回复?如果有的话,您介意发布答案吗? - ABeanSits
非常不幸,我还没有解决这个问题。但是现在,我仅仅依靠Keychain作为第一个WIP步骤。如果我从苹果那里得不到答案或者从其他开发人员那里获得某些经验故事,我可能会遵循苹果的文档并按建议保存凭据。如果没有其他情况,我也可以把今年的“苹果查询”用在上面。我在我的电脑上设置了提醒,一旦有更新,我 一定 会在这里发布它。 - Gero
1个回答

8
考虑到以下建议:
不要将共享的Web凭据用作安全用户凭据的主要存储。相反,将用户的凭据保存在钥匙串中,并仅在无法在钥匙串中找到登录凭据时使用共享的Web凭据。
主要问题在于共享Web凭据过程有点笨拙-它需要用户交互并花费时间来解决凭据。因此,如果用户已经通过您的应用程序进行了身份验证,则要避免完全显示登录页面。您可以通过将凭据存储在应用程序的钥匙串中来实现这一点,在此处,您可以立即访问它们而无需网络连接或用户权限。
这并不意味着您需要在钥匙串中存储用户的密码。通常,您会在钥匙串中存储类似OAuth访问令牌之类的内容。该令牌的存在意味着用户已通过身份验证-如果API端点拒绝您的令牌,则可以将其带回登录页面。
这个建议:
用户登录:应用程序在共享用户默认值中保存一个简单的标志,指示用户已登录。
可能是不安全的,具体取决于您在登录页面后面隐藏了什么内容,但通常任何属于用户的内容都需要有效的令牌才能访问,而不仅仅是用户默认值中的bool。
我认为这最符合用户意图(如果您删除密码,则不希望某些应用程序将其保留,直到您将其注销)
我不同意这一点;我不希望iOS应用程序因为我从Safari钥匙串中删除了密码而注销。

谢谢你。我感到有必要(嗯,“冲动”)回复你的一些观点,所以我编辑了问题。当然,这并不会改变你的答案的有效性,所以我接受了。干杯! - Gero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接