OAuth教程--原生应用的OAuth
本文是oauth.com上的教程的翻译。(原文地址)
本章介绍了在为原生应用程序支持OAuth时要记住的一些特殊注意事项。与基于浏览器的应用程序一样,原生应用程序无法在开发人员注册后保留客户端密钥,因为这需要开发人员在其应用程序的二进制版本中保存秘钥。目前已经证明,通过反编译提取秘钥是相对容易。因此,原生应用必须使用不需要秘钥的OAuth流程。
当前的行业最佳实践是在省略客户端密钥的同时使用授权流程,并使用外部用户代理来完成流程。外部用户代理通常是设备的原生浏览器(具有与原生应用程序不同的安全域),因此应用程序无法访问cookie存储或检查或修改浏览器内的页面内容。由于应用程序无法访问此情况下使用内部浏览器,因此这为设备提供了在授权不同应用程序时让用户保持登录的机会,这样他们无需在每次授权新应用程序时输入密码。
近年来,像iOS这样的平台一直在努力通过提供可以从应用程序内部启动的原生用户代理来进一步改善原生应用程序的OAuth用户体验,同时仍然与启动它的应用程序隔离。结果是用户不再需要离开应用程序以启动共享系统cookie的原生浏览器。这在iOS上称为SFSafariViewController。
针对原生应用程序的这些建议被发布为RFC 8252,这其中更详细地描述了这些概念。
使用系统浏览器
截至撰写本文时,许多原生应用程序仍然在应用程序内部的Web视图中嵌入OAuth界面。此方法存在多个问题,包括客户端应用程序可能会在登录时窃听用户输入其凭据,甚至提供虚假授权页面。以操作系统级别安全性的实现方式是嵌入式Web视图不与系统的原生浏览器共享cookie,因此用户的体验更糟糕,因为他们每次都需要输入密码。
完成授权流程的更安全和可信的方法是启动系统浏览器。然而,直到最近,这还有一个缺点,即应用程序弹出并启动浏览器,然后重定向回应用程序,这也不是一个理想的用户体验。
值得庆幸的是,移动平台一直在解决这个问题。在iOS 9和10中,开发人员现在可以使用SFSafariViewControllerAPI启动从应用程序内共享系统cookie的系统浏览器。这是通过API实现的,不允许客户端应用程序窥视浏览器,从而获得使用外部浏览器的安全优势以及用户在整个过程中保留在应用程序中的优秀用户体验。
强烈建议为iOS编写应用程序的原生应用程序开发人员使用SFSafariViewControllerAPI,如果API不可用,则启动外部Safari窗口(例如,如果应用程序需要支持iOS 8及更低版本)。
授权服务器应通过尝试检测授权URL是否在嵌入式Web视图中启动来强制执行此行为,如果是,则拒绝该请求。用于检测页面是否在嵌入式Web视图中与系统浏览器进行访问的特定技术将取决于平台,但通常涉及检查用户代理haeder。
重定向原生应用程序的URL
为了支持各种类型的原生应用程序,您的服务器需要支持注册三种类型的重定向URL,每种URL都支持稍微不同的用例。
自定义URL方案
某些平台(如iOS)允许应用程序注册自定义URL方案,只要在浏览器或其他应用程序中打开具有该方案的URL,该方案就会启动应用程序。支持具有自定义URL方案的重定向URL允许客户端启动外部浏览器以完成授权流程,然后在授权完成后重定向回应用程序。
应用程序开发人员应该选择全局唯一的URL方案,以及他们可以断言控制权的URL方案。由于操作系统通常没有关于特定应用程序是否已声明这种URL方案的注册的汇总,因此理论上两种应用程序可以独立地选择相同的方案,例如myapp://
。如果您希望帮助防止应用程序开发人员使用自定义方案时发生冲突,您应该建议(甚至强制执行)他们使用的方案是他们的反向域名模式。至少,您可以要求重定向URL至少包含一个.
以免与其他系统方案(如mailto或ftp)冲突。
例如,如果某个应用程序有一个相应的网站photoprintr.example.org
,则可以使用反向域名作为其URL方案org.example.photoprintr
。然后开发人员将注册org.example.photoprintr://
开头的重定向URL。通过强制执行此操作,您可以帮助鼓励开发人员选择不会与其他已安装的应用程序冲突的显式URL方案。
使用自定义URL方案的应用程序将正常启动授权请求,如授权请求中所述,但将提供具有其自定义URL方案的重定向URL。授权服务器仍应验证此URL是否已注册为允许的重定向URL,并且可将其视为Web应用程序注册的重定向URL一样的URL。
当授权服务器使用自定义方案将原生应用程序重定向到URL时,操作系统将启动应用程序并使原始应用程序可以访问整个重定向URL。该应用可以像常规OAuth 2.0客户端一样提取授权代码。
HTTPS URL匹配
某些平台允许应用程序注册URL模式,当系统浏览器访问的URL与注册模式的URL匹配时,应启动应用程序。这通常被应用程序用于“深层链接”到原生应用程序,例如在浏览器中查看Yelp URL时打开到Yelp应用程序的餐厅页面。
应用程序也可以使用此技术向URL注册一个模式,该模式将在授权服务器重定向回应用程序时启动应用程序。如果平台提供此功能,则这是原生应用程序的推荐选择,因为这提供了应用程序属于其匹配的URL的最大完整性。在平台不支持应用程序声明URL的情况下,这也提供了合理的后备选择。
loopback URL
原生应用程序可用于支持无缝重定向的另一种技术是在loopback接口的随机端口上打开新的HTTP服务器。这通常仅在桌面操作系统上完成,因为移动操作系统通常不向应用开发者提供此功能。
这种方法适用于命令行应用程序以及桌面GUI应用程序。该应用程序将启动HTTP服务器,然后开始授权请求,将重定向URL设置为loopback地址,例如http://127.0.0.1:49152/redirect
启动浏览器。当授权服务器将浏览器重定向回loopback地址时,应用程序可以从请求中获取授权代码。
为了支承实这种使用情况,授权服务器必须支持注册重定向URL以http://127.0.0.1:[port]/
或http://::1:[port]/
或http://localhost:[port]/
开始。授权服务器应允许任意路径组件以及任意端口号。请注意,在这种情况下,可以使用HTTP方案而不是HTTPS,因为请求永远不会离开设备。
注册
与服务器端应用程序一样,原生应用程序还必须使用授权服务器注册其重定向URL。这意味着除了服务器端应用程序的传统HTTPS URL之外,授权服务器还需要允许注册与上述所有模式匹配的重定向URL。
在授权服务器上启动授权请求时,服务器将验证所有请求参数,包括给定的重定向URL。授权应拒绝请求中无法识别的URL,以帮助避免授权代码拦截攻击。
PKCE扩展
由于原生平台上的重定向URL的强制执行能力是有限的,因此还有另一种获得额外安全性的技术,称为代码交换的证明秘钥,或简称PKCE。
此技术涉及原生应用程序创建初始随机密钥,并在交换访问令牌的授权代码时再次使用该秘密。这样,如果另一个应用程序截获授权代码,则在没有原始秘钥的情况下它将无法使用。
本地应用程序的服务器支持清单
要总结本章,您的授权服务器应支持以下内容,以便完全支持原生应用程序的安全授权。
- 允许客户为其重定向URL注册自定义URL方案。
- 支持loopback IP重定向具有任意端口号的URL,以支持桌面应用程序。
- 不要假设本机应用程序可以保守秘钥。要求所有应用程序声明它们是公开的还是保密的,并且只向机密应用程序发出客户秘钥。
- 支持PKCE扩展,并要求公共客户端使用它。
- 尝试检测并拒绝授权界面嵌入原生应用程序的Web视图的请求,要求其在系统浏览器中启动请求。