没有客户秘密的密码授予?

信息安全 移动的 oauth
2021-09-10 13:26:57

我正在努力决定如何从移动应用程序获取访问令牌。

我敢肯定这已经被覆盖过,但我找不到它。

我已经在我的 oauth2 服务器上启用了资源所有者凭据授权。授权需要客户端 ID、机密以及用户的用户名和密码。

如果我不想将我的客户端密码存储在我的移动应用程序中,如果存储在用户记录中的客户端 ID 值与从移动应用程序发送的客户端 ID 匹配,那么仅发送客户端 ID 并发出访问令牌是否安全?

这个用例的最佳实践是什么?

2个回答

你正在尝试做的事情有很多问题......

一般信息

“传统”方式的 OAuth2 不打算用于网络浏览器以外的任何东西。这意味着,如果您有桌面应用程序或移动应用程序,则不应使用“传统”OAuth2 进行身份验证。通过“传统”,我的意思是您被重定向到提供商网站以输入您的用户名/密码,然后使用将由客户端等使用的令牌重定向回来。

现在让我们开始解释...... OAuth2 文档一开始可能有点混乱。他们所说的客户端就是我们在开发Web应用程序时通常所说的服务器。OAuth2 有 3 个部分:

  1. 服务商:谷歌、脸书等
  2. 客户端(网络服务器、桌面应用程序、与服务提供商通信的移动应用程序)
  3. 用户(物理用户正在使用的应用程序)

移动和桌面应用程序的问题在于客户端和用户是同一事物,并且它们驻留在客户端计算机上。听说过“没有安全客户端”这句话吗?这在这里几乎适用。

问题 1:客户端密码

您不想将您的客户端密码放在移动应用程序中是正确的,因为您的应用程序可以“反编译”并且黑客会检索您的客户端密码。一旦他们拥有它,他们就可以创建自己的应用程序并模拟您的应用程序。

问题2:用户名/密码

不要在移动/桌面应用程序上使用“传统”OAuth2。这里的问题是您如何输入用户名/密码以及如何检索服务提供商在用户登录后提供给用户的令牌。让我们看看可能的方法来让它“安全地工作”......

失败尝试 1:要求您的用户直接通过您的界面输入用户名/密码。
不好的原因:恭喜,您刚刚窃取了所有用户的 Facebook 登录信息。

失败尝试 2:打开带有提供程序页面的浏览器。
不好的原因:你现在如何从浏览器取回令牌?没有办法得到它(除非你有一个恶意应用程序不断读取用户浏览器中的内容)

失败尝试3:打开一个假的浏览器来引诱用户给你它的登录信息。
不好的原因:与尝试 #1 相同。移动应用程序可以全屏显示并控制您看到的所有内容,因此您无法信任它们。桌面应用程序可以打开可以模仿您的浏览器等的新窗口。

一个严峻的事实是,如果没有充当“用户”的安全网络浏​​览器和充当“客户端”的 https 网络服务器,就无法使“传统”OAuth2 工作。

OAuth2 从未设计用于提供身份验证,而只是提供授权。两者有很大区别。OAuth2 协议被“破解”以使其也能够提供身份验证(检查 OpenId)。这个“hack”的唯一问题是它只能在 webbrowser 中工作,就像前面解释的那样。

真正的解决方案

如果您仍想继续使用 OAuth2/OpenID 进行登录并希望以安全的方式进行登录,那将与您想象的有所不同。使用 OAuth2 登录仍然是一个好主意,因为它可以为您的用户省去记住另一个用户名/密码的麻烦。

  1. 您将需要一个服务器来存储您的客户端 ID 和密码。您的移动应用程序将连接到此服务器以发送令牌。

  2. 当要求登录时,将用户重定向到浏览器中的服务提供商网页。或者,用户可以直接访问您的 https 网站进行登录,该网站将再次重定向他们。服务提供商网页是您输入登录信息的唯一地方。

  3. 创建一个 https 网页,用户在使用服务提供商登录后将能够在其中看到令牌。

  4. 要求用户将此令牌复制到您的应用程序中。然后,您的应用程序将令牌发送到您的服务器。服务器添加客户端 ID 和客户端密码并将其转发给服务提供者。

您的用户现在可以使用他们的“facebook”登录来登录您的应用程序,您的应用程序无法窃取他们的登录信息或黑客窃取您的客户端机密。

附加说明

在网络浏览器之外使用的网络钓鱼攻击和 OAuth2 也是一个有趣的例子,但这将是另一个问题的主题。

我相信这里有一个相关的对话https://stackoverflow.com/questions/19615372/client-secret-in-oauth-2-0但并不是真正解决这个问题。

如果您担心没有在应用程序中对密码进行硬编码,从而导致重新编译出现问题,那么一种解决方案可能是使用辅助服务器来安全地存储可以使用您要求的不同用户名/密码下载的密码即流程的用户:

  1. 要求用户提供用户名和/或密码

  2. 使用这些凭据登录返回秘密的安全服务

  3. 按预期使用秘密(不要在本地存储!)

这需要更多的工作和管理,但它确实为硬编码的秘密问题提供了安全的解决方案。