nos*_*tio 7 windows security native web-applications oauth-2.0
这个问题是对“ 在本机应用程序和网站之间共享凭据 ”的补充,因为我们的目标是在相反的方向上共享秘密。
TL; TR:我们如何安全地从Web浏览器应用程序向Native Desktop应用程序共享用户的身份验证/授权状态,因此同一用户不必在Native应用程序中另外进行身份验证?
TS; WM:我们正在研究以下架构:Web应用程序(在用户选择的Web浏览器中运行一些HTML前端UI),本机桌面应用程序(实现自定义协议处理程序),Web API和OAuth2服务,如图所示。

最初,使用授权代码授予流程针对OAuth2服务在Web浏览器应用程序中对用户进行身份验证/授权。
然后,当用户单击我们的基于协议的自定义超链接时,Web浏览器内容可以与本机应用程序进行单向对话。基本上,已经完成了通过Web API在两者之间建立安全的双向后端通信通道的工作。
我们认为,在对通过自定义协议链接从Web浏览器应用程序收到的任何请求采取行动之前,本机应用程序应首先对用户进行身份验证(使用该特定的桌面会话该用户应该是同一个人)。我们认为本机应用程序还应该使用授权码流(带有PKCE)来获取Web API的访问令牌。然后,它应该能够使用相同的Web API安全地验证自定义协议数据的来源和完整性。
但是,对于用户来说,必须两次进行身份验证可能是一个障碍,第一次是在Web浏览器中,第二次是在Native应用程序中,两者同时运行。
因此,存在一个问题:是否有一种方法可以在不损害此体系结构的客户端安全性的情况下,将OAuth2访问令牌(或任何其他授权承载)从Web浏览器应用安全地传递到本机应用?也就是说,Native应用程序可以使用Web浏览器中的身份调用Web API,而不必先验证同一用户?
就个人而言,我看不到如何安全地避免其他身份验证流程。默认情况下,通过自定义应用程序协议进行的通信是不安全的,因为通常这只是调用本机应用程序的命令行参数。与TLS通道不同,它可以被拦截,模拟等。我们可以对自定义协议数据进行加密。尽管如此,无论对本机应用程序进行什么调用来解密(无论是对客户端OS API还是对Web API的一些不受保护的调用),都必须执行,恶意的actor /恶意软件也可能会复制它们。
我想念什么吗?是否有特定于平台的安全解决方案?本机桌面应用程序是Electron应用程序,旨在跨平台。我们的大多数用户都将使用任何受支持的浏览器(甚至包括IE11)在Windows上运行此程序,但是毫无疑问ActiveX或入侵正在运行的Web浏览器实例。
最佳解决方案:使用自定义 URL 方案进行单点登录 (SSO)
当我检查你的问题时,我想起了我在办公室使用的 Zoom 应用程序。怎么运行的 ?
我将我的 Gmail 帐户链接到 Zoom 帐户(这是帐户链接,这超出了实施范围)。当我打开 Zoom 应用程序时,我可以选择使用 Gmail 登录的选项。这将打开我的浏览器并转到 Gmail。如果我登录 Gmail,我会被重定向回要求我启动 Zoom 应用程序的页面。这个应用程序的启动是如何发生的?当应用程序安装时,应用程序会注册一个自定义 URL 方案,并且浏览器中的最终重定向会瞄准此 URL。此 URL 传递一个临时机密,Zoom 应用程序使用该临时机密来获取 OAuth 令牌。令牌获取是独立于浏览器完成的,通过 SSL 直接调用 OAuth 服务器的令牌端点。
这是本机应用程序的授权代码流。这就是移动应用程序使用 OAuth 的方式。您的主要问题(不允许用户重新登录)已解决。这就是 SSO 的实际应用。
有一个规范定义了围绕此机制的最佳实践。我欢迎您阅读RFC8252 - OAuth 2.0 for Native Apps。
挑战
您需要为每个应用程序发行版实现特定于操作系统的本机代码。Windows、Mac 和 Linux 对自定义 URL 方案有不同的实现支持。
建议
对于所有 OAuth 授权类型,PKCE 都是强制性的(用 IETF 的话来说应该)。有一个正在进行的草案讨论了这一点。因此,在您的实现中也包括 PKCE。
使用 PKCE,可以防止重定向/回调响应被窃取。即使某些其他应用程序拦截回调,也无法重新创建令牌请求,因为 PKCE code_verifer 在那里。
另外,不要使用自定义解决方案,例如通过另一个通道传递秘密。这将使维护工作变得复杂。由于此流程已存在于 OAuth 中,因此您可以从库和指导中受益。
-------------------------------------------------- ---
更新:保护令牌请求
虽然自定义 URL 方案解决了启动本机应用程序的问题,但保护令牌请求可能具有挑战性。有多种选择可供考虑。
- 将本机应用程序启动与从浏览器共享的秘密绑定
当基于浏览器的客户端启动本机客户端时,它可以调用自定义 API 来生成密钥。此秘密的作用类似于一次性密码 (OTP)。用户必须在本机应用程序中输入此值才能获取令牌。这是授权代码流之上的自定义。
- 动态客户端注册和动态客户端身份验证
OAuth 规范不鼓励将机密嵌入公共客户端。但正如问题所有者指出的那样,某些恶意应用程序可能会自行注册以接收自定义 URL 响应并获取令牌。在这种情况下,PKCE 可以提供额外的安全层。
但仍然在极端情况下,如果恶意应用程序注册了 URL 并使用 PKCE 作为原始应用程序,则可能存在潜在威胁。
一种选择是允许在应用程序第一次启动时进行动态客户端注册。这里,安装程序/分发可以包括与 DCR 一起使用的秘密。
此外,还可以通过专用服务使用动态客户端身份验证。此处,应用程序的令牌请求包含由自定义服务颁发的临时令牌。定制服务受到本机应用程序的挑战。这可以通过totp或基于嵌入秘密的加密绑定来完成。还可以利用通过浏览器发出的 OTP(如第一个注释中所述),该 OTP 需要由最终用户手动复制粘贴。一旦经过验证,该服务就会发出与该秘密相关的令牌。在令牌请求中,本机客户端发送此令牌以及回调值。通过这种方式,即使我们增加了实现的复杂性,我们也减少了威胁向量。
概括
正如您所提到的,使用自定义协议处理程序并不是传递机密的安全方法,因为另一个应用程序可能会处理您的协议并拦截该机密。
如果您施加严格的约束,即本机应用程序和Web应用程序之间的通信通道是从Web应用程序发起的,并且本机应用程序之前没有建立安全通道(例如可以加密其他秘密的共享秘密),那么无法将机密安全地传输到本机应用程序。
想象一下,如果这是可能的,那么 PKCE 在 OAuth 2.0 代码流中将是多余的,因为服务器可以安全地传输访问令牌来响应授权请求,而不是要求code_verifier在获取访问令牌时提供授权。
| 归档时间: |
|
| 查看次数: |
674 次 |
| 最近记录: |