【问题标题】:Share credentials between native app and web site在本机应用程序和网站之间共享凭据
【发布时间】:2017-08-25 04:10:16
【问题描述】:

我正在开发的一个应用程序允许用户登录启用 OAuth 的后端。因此,应用程序仅对身份验证令牌和用户元数据私有,而不对用户的凭据私有。

在应用程序中,用户可以点击在浏览器中打开链接的链接。这些资源也受到 OAuth 的保护,登录原生应用时获得的令牌也与 web 相关。

我希望用户的凭据以标准 OAuth 方式从本机应用程序流向网络浏览器(通过将其包含为 Authorization 标头)。

Android 似乎通过其shared credentials 功能促进了这一点,但我找不到适用于 iOS 的等价物。我确实找到了shared web credentials 功能,但这似乎需要了解用户的凭据。

如何将 OAuth 令牌从我的本机应用程序传送到它打开的 Web 浏览器?

【问题讨论】:

  • related question 中,我们希望将网络浏览器中的秘密分享到本机应用程序。

标签: ios security safari oauth-2.0


【解决方案1】:

为什么不使用内置的苹果函数和库?

看看shared web credential

要在您的应用中启用共享凭据,请将 com.apple.developer.associated-domains 键添加到您应用的权利中。您可以使用目标的功能窗格添加此权利(参见图 1)。

或使用iCloud Keychain

本文档重点介绍使用钥匙串服务来存储和检索密码。如果您的应用程序需要处理以下密码,请阅读本文档:

多个用户——例如,必须对多个用户进行身份验证的电子邮件或调度服务器

多台服务器 - 例如,银行或保险应用程序,可能需要与多个安全数据库服务器交换信息

需要输入密码的用户——例如,网络浏览器,它可以使用钥匙串来存储用户在多个安全网站上所需的密码

希望对你有帮助

【讨论】:

    【解决方案2】:

    技术上,你可以在传递给浏览器的 URI 中包含令牌。

    但这会不安全:

    注入访问令牌

    额外的(并且非常危险的)威胁 当客户端接受来自其他来源的访问令牌时发生 从令牌端点返回调用。这可能发生在客户端 使用隐式流(其中令牌直接作为 URL 哈希中的参数)并且没有正确使用 OAuth 状态 范围。如果一个不同的部分也可能发生此问题 应用程序在组件之间传递访问令牌,以便 在他们之间“共享”访问。这是有问题的,因为它打开了一个 访问令牌可能被注入应用程序的地方 由外部方(并可能泄漏到应用程序之外)。 如果客户端应用程序不通过验证访问令牌 某种机制,它无法区分有效令牌 和一个攻击令牌。

    (来源:https://oauth.net/articles/authentication/

    规范中也是禁止的:

    访问令牌凭据(以及任何机密访问令牌 属性)必须在运输和存储过程中保密,并且仅 在授权服务器之间共享,资源服务器访问 令牌有效,以及向其颁发访问令牌的客户端。

    (来源:https://www.rfc-editor.org/rfc/rfc6749#section-10.3

    因此,您可以尝试使用另一种 OAuth 流程,称为“授权代码流程”,该流程不是将令牌传递给浏览器,而是应用程序传递一个特殊代码,然后浏览器使用该代码从服务器。

    但是,您的用例并不完全是创建此机制的目的,因此我不确定使用它来完成您所追求的是否符合规范。

    【讨论】:

      【解决方案3】:

      首先你应该使用 HTTPS 协议 - google for:让我们加密(以获得免费的 SSL 证书)

      您应该考虑的流程:

      1. 用户打开您的移动应用程序并提示输入他们的用户名 或电子邮件和密码。

      2. 您从移动应用向 API 服务发送 POST 请求 包含用户的用户名或电子邮件和密码数据(OVER SSL!)。

      3. 您验证用户凭据,并为 在一定时间后过期的用户。 (google for:api 速率限制)

      4. 您将此访问令牌存储在移动设备上,将其视为 一个 API 密钥,可让您访问您的 API 服务。

      5. 一旦访问令牌过期且不再有效,您重新提示 用户名或电子邮件和密码。

      在服务器端,您应该使用以下内容:fail2ban、iptables,并确保您使用的 linux 版本是最新的。 (您应该不时更新/升级)

      在 Web 应用程序 (api) 上,您应该验证并序列化所有数据。永远不要发送更多需要的数据,也永远不要接受来自客户端的部分数据。在 api 应用程序上,您应该进行 xss(跨站点脚本)/csrf(跨站点请求伪造)预防。看看 OWASP TOP 10 - https://www.owasp.org/index.php/Top_10_2013-Top_10 。您还应该在 web api 上使用安全标头 - https://www.dionach.com/blog/an-overview-of-http-security-headers

      永远不要相信用户输入。

      【讨论】:

        【解决方案4】:

        关联域和共享 Web 凭据在这里似乎不是一个好方法。

        你有两个选择:

        1. 将 OAuth 访问令牌作为 URL-QueryString-Param 传递给 网页浏览器。 https://x.y.z/?access_token=abc 您必须操作嵌入的 URL 并确保您的后端理解这一点。 非常常见和简单的方法。许多网站,如 Facebook 和 Google 正在 URL 中传递访问令牌。
        2. 如果您使用的是应用内浏览器(UIWebView、WKWebView),您可以拦截 URL-Request 并自行添加授权标头。 UIWebView 见this,WKWebView 见this(这比 UIWebView 难一点)

        【讨论】:

        • 或者让浏览器自己作为客户端运行,并以额外的重定向为代价获得自己的令牌
        • @HansZ。你能解释一下你的意思是“让浏览器自己作为客户端运行并以额外的重定向为代价获得自己的令牌”吗?非常感谢。
        • 即使使用 TLS,在 URL 中发送访问令牌也不是一种安全的方法,因为它可以在各个地方清晰地检查,例如浏览器历史记录、服务器日志、Referer Header(即例如发送给第三方分析服务)。
        猜你喜欢
        • 2011-06-03
        • 1970-01-01
        • 1970-01-01
        • 2015-07-22
        • 2020-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多