我尝试为Web服务实现OAuth 2提供程序,然后在其上构建本机应用程序。此外,我希望为第三方开发人员提供API访问权限。
我已经阅读了OAuth 2规范,无法选择正确的流程。我也想验证CLI和GUI应用程序。
首先,我们有两种客户类型 - 公共和机密。当然,GUI和CLI应用程序都是公开的。但这两种类型有什么区别?在这种情况下我需要client_secret,如果我只是通过更改客户端类型来获取访问令牌吗?
我试着看看像GitHub这样的流行服务的一些API实现。但他们使用HTTP Basic Auth。不确定这是个好主意。
可用性(CLI中的旧登录名和密码比打开Web浏览器更舒服)和安全性之间有什么区别?
谢谢!
答案 0 :(得分:10)
关于公共和机密客户之间的区别,请参阅http://tutorials.jenkov.com/oauth2/client-types.html,其中包含:
机密客户端是一个能够保存的机密客户端 客户密码对世界保密。这个客户端密码是 授权服务器分配给客户端应用程序。这个密码 用于向授权服务器标识客户端,以避免 欺诈行为。机密客户端的示例可以是Web应用程序,其中 除了管理员之外,没有人可以访问服务器,并且可以看到 客户密码。
公共客户端是一个无法保留的应用程序 客户密码保密。例如,移动电话应用程序 或嵌入了客户端密码的桌面应用程序 它。这样的应用程序可能会被破解,这可能会揭示出来 密码。对于在其中运行的JavaScript应用程序也是如此 用户浏览器。用户可以使用JavaScript调试器进行查看 应用程序,并查看客户端密码。
机密客户端比公共客户端更安全,但您可能无法始终使用机密客户端,因为它们运行的环境受到限制(c.q.本机应用程序,浏览器内客户端)。
答案 1 :(得分:1)
@HansZ的答案是一个很好的起点,因为它阐明了公共客户端应用程序和私有客户端应用程序之间的区别:将客户端秘密保密的功能。
但是它不能回答问题:在哪些用例中应该使用哪个OAuth2配置文件?要回答这个关键问题,我们需要更深入地研究这个问题。
对于机密应用程序,通常通过配置(例如,在属性文件中)带外(OOB)提供客户机密。对于基于浏览器的应用程序和移动应用程序,实际上没有任何执行任何配置的机会,因此,这些被认为是公共应用程序。
到目前为止,太好了。但我不同意这会使此类应用程序无法接受或存储刷新令牌。实际上,SPA和移动应用所使用的重定向URI通常为localhost
,因此100%等效于响应资源所有者密码凭据授予(ROPC)直接从令牌服务器接收令牌。>
许多作者有时甚至正确地指出,OAuth2实际上并未进行身份验证。实际上,如OAuth2 RFC 6749所述,ROPC和客户端Credentias(CC)授予都需要执行身份验证。参见Section 4.3和Section 4.4。
但是,该声明对于Authorization Code
和Implicit
授权是正确的。但是,身份验证实际上如何在这些域中起作用?
通常,用户在浏览器表单中输入其用户名和密码,该表单将发布到身份验证服务器,身份验证服务器为其域设置cookie。抱歉,但即使在2019年,cookie仍是认证技术的现状。为什么?因为cookie是浏览器应用程序维护状态的方式。它们没有什么问题,浏览器cookie的存储是相当安全的(受域保护,JS应用程序不能使用“仅HTTP” cookie,安全需要TLS / SSL)。 Cookies允许仅在第一个授权请求上显示登录表单。之后,将重用当前的身份(直到会话过期)。
好,那么以上内容与ROPC有什么不同?不多。不同之处在于登录表单的来源。在SPA中,已知该应用程序来自经过TLS / SSL认证的服务器。因此,这与由服务器直接呈现表单完全相同。无论哪种方式,您都可以通过TLS / SSL信任该站点。对于移动应用程序,该表单已知是通过应用程序签名通过应用程序开发人员提供的(来自Google Play,Apple Store等的应用程序已签名)。因此,再次有一种类似于TLS / SSL的信任机制(更好,更糟,取决于存储,CA,受信任的根分发等)。
在两种情况下,都将返回令牌,以防止应用程序必须在每次请求时都重新发送密码(这就是HTTP Basic身份验证错误的原因)。
在这两种情况下,都必须使身份验证服务器经受任何面向Internet的登录服务器遭受攻击的攻击。授权服务器没有太多问题,因为它们委托身份验证。但是,OAuth2 password
和client_credentials
配置文件都可以用作事实上的身份验证服务器,因此,确实需要严格。
为什么您更喜欢ROPC而不是HTML表单?非交互式案例(例如CLI)是常见的用例。大多数CLI可以被认为是机密的,因此应该同时具有client_id
和client_secret
。请注意,如果在共享的OS实例上运行,则应编写CLI来从文件或至少从标准输入中拉出客户机密钥和密码,以避免在进程列表中显示密钥和密码!
本机应用程序和SPA是imo的另一个好用法,因为这些应用程序需要令牌才能传递给REST服务。但是,如果这些应用程序也需要Cookie进行身份验证,那么您可能要使用授权码或隐式流,并将身份验证委派给常规的Web登录服务器。
同样,如果未在与资源服务器相同的域中对用户进行身份验证,则确实需要使用授权码或隐式授予类型。权限服务器取决于用户如何进行身份验证。
如果使用2要素身份验证,事情会变得很棘手。我本人还没有过这座特别的桥。但是我已经看到像Attlassian这样的情况,可以使用API密钥来允许访问通常需要密码之外第二个因素的帐户。
请注意,即使您在服务器上托管HTML登录页面,也需要注意,该页面不会被浏览器中的IFRAME或本机应用程序中的某些Webview组件包装(可能可以设置挂钩)来查看您输入的用户名和密码(密码管理器的工作方式,顺便说一句)。但这是“登录服务器强化”下的另一个主题,但是答案都涉及到客户端遵守Web安全约定,从而尊重应用程序一定程度的信任。
一些最后的想法:
如果刷新令牌通过任何流类型安全地传递到应用程序,则可以将其安全地存储在浏览器/本地本地存储中。浏览器和移动设备可以很好地保护此存储。当然,它比仅在内存中存储刷新令牌的安全性低。因此,也许不适合银行应用程序……但是,许多应用程序的会话寿命很长(几周),这就是完成的过程。
请勿将客户端机密用于公共应用程序。这只会给您一种错误的安全感。客户端机密仅在存在安全的OOB机制来传递机密并将其安全存储(例如,锁定的OS权限)时才适用。