在使用OAuth2的“资源所有者密码凭据”授予类型时,如何对客户端凭据进行保密

问题描述

| 我们正在建立一个休息服务,我们想使用OAauth 2进行授权。当前的草案(5月19日起为v2-16)描述了四种补助类型。它们是用于获得授权(访问令牌)的机制或流程。 授权码 隐性补助金 资源所有者凭证 客户凭证 似乎我们需要支持它们全部四个,因为它们有不同的用途。前两个(可能还有最后一个)可以从需要访问API的第三方应用程序中使用。授权代码是对足以幸运地驻留在安全服务器上的Web应用程序进行授权的标准方法,而隐式授予流将是无法完全对其凭据保密的客户端应用程序(例如,移动/台式机)的选择。应用程序,JavaScript客户端等)。 我们希望自己使用第三种机制来在移动设备上提供更好的用户体验–而不是将用户带到Web浏览器中的登录对话框等,用户只需在应用程序中直接输入其用户名和密码即可。并登录。 我们还希望使用“客户端凭据”授予类型来获取可用于查看公共数据的访问令牌,而不与任何用户相关联。在这种情况下,这与其说是授权,不如说是类似于API密钥的一种,我们仅用于授予已向我们注册的应用程序的访问权限,并为我们提供了根据需要撤消访问权限的选项。 所以我的问题是: 您认为我正确理解了不同赠款类型的目的吗? 您如何对客户凭据保密?在第三种情况和第四种情况下,我们都需要在客户机上的某个位置具有客户机ID和客户机密钥,这听起来不是一个好主意。 即使您使用隐式授予类型并且不公开您的客户端机密,是什么阻止另一个应用程序使用相同的授权机制和您的客户端ID来模拟您的应用程序? 总而言之,我们希望能够使用来自客户端应用程序的客户端凭证和资源所有者凭证流。这两个流程都要求您以某种方式存储客户端机密,但是客户端是移动或JavaScript应用程序,因此很容易被盗。     

解决方法

我面临类似的问题,而且对于OAuth来说还比较陌生。我已经在我们的API中实现了“资源所有者密码凭据”,供我们的官方移动应用程序使用-网络流量似乎非常糟糕,无法在移动平台上使用,并且一旦用户安装一个应用程序,并相信它是我们的官方应用程序,因此他们应该可以轻松地直接在该应用程序中输入用户名/密码。 正如您所指出的,问题是我的API服务器无法安全地验证应用程序的client_id。如果我在应用程序代码/程序包中包含一个client_secret,那么安装该应用程序的任何人都可以看到它,因此,要求client_secret不会使该过程更加安全。因此,基本上,任何其他应用程序都可以通过复制client_id来模拟我的应用程序。 只是为了直接回答您的每一点: 我会继续阅读规范的不同草案,以查看是否有任何更改,并且主要关注“资源所有者密码凭据”部分,但是我认为您是对的。客户凭证(4)我认为,内部或第三方服务也可能会使用它们,它们可能需要访问的不仅仅是“公共”信息,例如您可能具有分析能力或需要获取所有信息的东西用户。 我认为您不能对客户端保密。 没有什么可以阻止其他人使用您的客户ID。这也是我的问题。一旦代码离开服务器并作为应用程序安装或在浏览器中以Javascript运行,您就无法假设任何秘密。 对于我们的网站,我们遇到了与您在“客户端凭据”流程中描述的问题类似的问题。我最终要做的是将身份验证转移到服务器端。用户可以使用我们的Web应用程序进行身份验证,但是我们API的OAuth令牌存储在服务器端,并与用户的Web会话相关联。 Javascript代码发出的所有API请求实际上都是对Web服务器的AJAX调用。因此,浏览器不直接通过API进行身份验证,而是具有经过身份验证的Web会话。 似乎您的客户端凭据用例有所不同,因为您正在谈论第三方应用程序,并且仅通过此方法提供公共数据。我认为您的担心是正确的(任何人都可以窃取和使用其他人的API密钥),但是如果您只需要免费注册就可以获取API密钥,那么我不明白为什么有人会真正想要窃取一个。 您可以监视/分析每个API密钥的使用情况,以尝试检测滥用情况,这时您可以使一个API密钥无效并为合法用户提供一个新的API密钥。这可能是最好的选择,但绝不是安全的。 如果您想将其锁定得更紧一点,也可以使用类似“刷新令牌”的方案,尽管我不知道您将获得多少收益。如果您每天使暴露于Javascript的api令牌过期一次,并且要求第三方使用(秘密)刷新令牌进行某种服务器端刷新,则被盗的api令牌永远不会超过一天。可能会鼓励潜在的令牌窃贼改而注册。但是,其他所有人都会感到痛苦,因此不确定是否值得。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...