我尝试为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本机应用程序,浏览器内客户端).
@HansZ 的答案是一个很好的起点,因为它澄清了公共和私人客户端应用程序之间的区别:保持客户端秘密的能力。
但它没有回答这个问题:对于哪些用例我应该使用什么 OAuth2 配置文件?为了回答这个关键问题,我们需要更深入地研究这个问题。
对于机密应用程序,客户端机密通常通过配置(例如在属性文件中)带外 (OOB) 提供。对于基于浏览器的移动应用程序,实际上没有任何机会执行任何配置,因此,这些应用程序被视为公共应用程序。
到目前为止,一切都很好。但我不同意这会使此类应用程序无法接受或存储刷新令牌。事实上,SPA 和移动应用程序使用的重定向 URI 通常localhost100% 相当于直接从令牌服务器接收令牌以响应资源所有者密码凭证授予 (ROPC)。
许多作者指出,OAuth2 实际上并不进行身份验证,有时是正确的。事实上,正如 OAuth2 RFC 6749 中所述,执行身份验证需要 ROPC 和客户端凭证 (CC) 授权。参见第 4.3 节和第 4.4 节。
然而,该声明对于Authorization Code和Implicitgrants 是正确的。但是这些域的身份验证实际上是如何工作的呢?
通常,用户在浏览器表单中输入用户名和密码,该表单会发布到身份验证服务器,身份验证服务器会为其域设置 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 基本身份验证不好的原因)。
在这两种情况下,身份验证服务器都必须经过强化,以抵御任何面向互联网的登录服务器所遭受的攻击。授权服务器不会有太多这个问题,因为它们委托身份验证。然而,OAuth2password和client_credentials配置文件都充当事实上的身份验证服务器,因此确实需要很严格。
为什么您更喜欢 ROPC 而不是 HTML 表单?非交互式案例(例如 CLI)是常见的用例。大多数 CLI 可以被视为机密,因此应该同时具有client_id和client_secret。请注意,如果在共享操作系统实例上运行,您应该编写 CLI 来从文件中提取客户端密码和密码,或者至少从标准输入中提取,以避免密码和密码出现在进程列表中!
在我看来,本机应用程序和 SPA 是另一个很好的用途,因为这些应用程序需要令牌才能传递到 REST 服务。但是,如果这些应用程序也需要 cookie 进行身份验证,那么您可能需要使用授权代码或隐式流程并将身份验证委托给常规 Web 登录服务器。
同样,如果用户未在与资源服务器相同的域中进行身份验证,则确实需要使用授权代码或隐式授权类型。用户必须如何进行身份验证取决于授权服务器。
如果使用两因素身份验证,事情就会变得棘手。我自己还没有走过这座桥。但我见过像 Attlassian 这样的案例,可以使用 API 密钥来允许访问通常需要密码以外的第二个因素的帐户。
请注意,即使您在服务器上托管 HTML 登录页面,您也需要注意它不会被浏览器中的 IFRAME 或本机应用程序中的某些 Webview 组件(可能能够设置挂钩来查看您输入的用户名和密码,这就是密码管理器的工作原理,顺便说一句)。但这是属于“登录服务器强化”的另一个主题,但答案都涉及客户尊重网络安全约定,因此对应用程序有一定程度的信任。
最后一些想法:
如果刷新令牌通过任何流类型安全地传递到应用程序,则它可以安全地存储在浏览器/本机本地存储中。浏览器和移动设备可以很好地保护此存储。当然,它的安全性不如仅将刷新令牌存储在内存中。所以也许不适用于银行应用程序......但是很多应用程序都有很长的会话(数周),这就是它的完成方式。
不要将客户端机密用于公共应用程序。它只会给你一种虚假的安全感。仅当存在安全的 OOB 机制来传递机密并且安全存储该机密(例如锁定操作系统权限)时,客户端机密才适用。
| 归档时间: |
|
| 查看次数: |
4730 次 |
| 最近记录: |