OAuth 2用于本机应用程序 - 公共和机密客户端类型之间有什么区别?

ssb*_*sbb 12 oauth oauth-2.0

我尝试为Web服务实现OAuth 2提供程序,然后在其上构建本机应用程序.此外,我希望为第三方开发人员提供API访问权限.

我已经阅读了OAuth 2规范,无法选择正确的流程.我也想验证CLI和GUI应用程序.

首先,我们有两种客户类型 - 公共和机密.当然,GUI和CLI应用程序都是公开的.但这两种类型有什么区别?在这种情况下我需要client_secret如果我只是通过更改客户端类型就可以获得访问令牌?

我试着看一些流行服务的一些API实现,比如GitHub.但他们使用HTTP Basic Auth.不确定这是个好主意.

在可用性(CLI中的旧登录和密码比打开Web浏览器更舒适)和安全性之间选择了什么?

谢谢!

Han*_* Z. 14

关于公共和机密客户之间的区别,请参阅http://tutorials.jenkov.com/oauth2/client-types.html,其中说:

机密客户端是一种能够将客户密码保密的应用程序.此客户端密码由授权服务器分配给客户端应用程序.此密码用于向授权服务器标识客户端,以避免欺诈.机密客户端的示例可以是Web应用程序,除了管理员之外,没有人可以访问服务器,并且可以看到客户端密码.

公共客户端是一种无法保密客户端密码的应用程序.例如,移动电话应用程序或嵌入了客户端密码的桌面应用程序.这样的应用程序可能会被破解,这可能会泄露密码.对于在用户浏览器中运行的JavaScript应用程序也是如此.用户可以使用JavaScript调试器查看应用程序,并查看客户端密码.

机密客户端比公共客户端更安全,但您可能无法始终使用机密客户端,因为它们运行的​​环境受到限制(cq本机应用程序,浏览器内客户端).

  • 公共客户不会知道如何将刷新令牌保密,这就是为什么不应向其发行令牌的原因;与公共客户端相关联的唯一安全性是强制性预注册重定向URI的形式,令牌将在其中传递 (2认同)

Cha*_*zel 7

@HansZ 的答案是一个很好的起点,因为它澄清了公共和私人客户端应用程序之间的区别:保持客户端秘密的能力。

但它没有回答这个问题:对于哪些用例我应该使用什么 OAuth2 配置文件?为了回答这个关键问题,我们需要更深入地研究这个问题。

对于机密应用程序,客户端机密通常通过配置(例如在属性文件中)带外 (OOB) 提供。对于基于浏览器的移动应用程序,实际上没有任何机会执行任何配置,因此,这些应用程序被视为公共应用程序。

到目前为止,一切都很好。但我不同意这会使此类应用程序无法接受或存储刷新令牌。事实上,SPA 和移动应用程序使用的重定向 URI 通常localhost100% 相当于直接从令牌服务器接收令牌以响应资源所有者密码凭证授予 (ROPC)。

许多作者指出,OAuth2 实际上并不进行身份验证,有时是正确的。事实上,正如 OAuth2 RFC 6749 中所述,执行身份验证需要 ROPC 和客户端凭证 (CC) 授权。参见第 4.3 节第 4.4 节

然而,该声明对于Authorization CodeImplicitgrants 是正确的。但是这些域的​​身份验证实际上是如何工作的呢?

通常,用户在浏览器表单中输入用户名和密码,该表单会发布到身份验证服务器,身份验证服务器会为其域设置 cookie。抱歉,即使在 2019 年,cookie 仍然是最先进的身份验证技术。为什么?因为 cookie 是浏览器应用程序维护状态的方式。它们没有任何问题,并且浏览器 cookie 存储相当安全(域受保护,JS 应用程序无法获取“仅 http”cookie,安全需要 TLS/SSL)。Cookie 允许仅在第一次授权请求时显示登录表单。之后,将重新使用当前身份(直到会话过期)。

好吧,那么上面和ROPC有什么不同呢?不多。区别在于登录表单的来源。在 SPA 中,已知应用程序来自 TLS/SSL 身份验证的服务器。因此,这与服务器直接呈现表单几乎相同。无论哪种方式,您都通过 TLS/SSL 信任该网站。对于移动应用程序,该表单已知来自应用程序开发人员通过应用程序签名(来自 Google Play、Apple Store 等的应用程序已签名)。因此,再次强调,存在类似于 TLS/SSL 的信任机制(没有更好,也没有更差,取决于商店、CA、受信任的根发行版等)。

在这两种情况下,都会返回一个令牌,以防止应用程序必须在每次请求时重新发送密码(这就是 HTTP 基本身份验证不好的原因)。

在这两种情况下,身份验证服务器都必须经过强化,以抵御任何面向互联网的登录服务器所遭受的攻击。授权服务器不会有太多这个问题,因为它们委托身份验证。然而,OAuth2passwordclient_credentials配置文件都充当事实上的身份验证服务器,因此确实需要很严格。

为什么您更喜欢 ROPC 而不是 HTML 表单?非交互式案例(例如 CLI)是常见的用例。大多数 CLI 可以被视为机密,因此应该同时具有client_idclient_secret。请注意,如果在共享操作系统实例上运行,您应该编写 CLI 来从文件中提取客户端密码和密码,或者至少从标准输入中提取,以避免密码和密码出现在进程列表中!

在我看来,本机应用程序和 SPA 是另一个很好的用途,因为这些应用程序需要令牌才能传递到 REST 服务。但是,如果这些应用程序也需要 cookie 进行身份验证,那么您可能需要使用授权代码或隐式流程并将身份验证委托给常规 Web 登录服务器。

同样,如果用户未在与资源服务器相同的域中进行身份验证,则确实需要使用授权代码或隐式授权类型。用户必须如何进行身份验证取决于授权服务器。

如果使用两因素身份验证,事情就会变得棘手。我自己还没有走过这座桥。但我见过像 Attlassian 这样的案例,可以使用 API 密钥来允许访问通常需要密码以外的第二个因素的帐户。

请注意,即使您在服务器上托管 HTML 登录页面,您也需要注意它不会被浏览器中的 IFRAME 或本机应用程序中的某些 Webview 组件(可能能够设置挂钩来查看您输入的用户名和密码,这就是密码管理器的工作原理,顺便说一句)。但这是属于“登录服务器强化”的另一个主题,但答案都涉及客户尊重网络安全约定,因此对应用程序有一定程度的信任。

最后一些想法:

  1. 如果刷新令牌通过任何流类型安全地传递到应用程序,则它可以安全地存储在浏览器/本机本地存储中。浏览器和移动设备可以很好地保护此存储。当然,它的安全性不如仅将刷新令牌存储在内存中。所以也许不适用于银行应用程序......但是很多应用程序都有很长的会话(数周),这就是它的完成方式。

  2. 不要将客户端机密用于公共应用程序。它只会给你一种虚假的安全感。仅当存在安全的 OOB 机制来传递机密并且安全存储该机密(例如锁定操作系统权限)时,客户端机密才适用。