OAuth教程--重定向URI
本文是oauth.com上的教程的翻译。(原文地址)
重定向网址是OAuth流程的重要组成部分。用户成功授权应用程序后,授权服务器将带着URL中的授权码或访问令牌将用户重定向回应用程序。由于重定向URL将包含敏感信息,因此服务不会将用户重定向到任意位置就显得至关重要。
确保用户仅被定向到适当位置的最佳方法是要求开发人员在创建应用程序时注册一个或多个重定向URL。在这些部分中,我们将介绍如何处理移动应用程序的重定向URL,如何验证重定向URL以及如何处理错误。
重定向URI注册
为了确保服务的安全性,您必须要求开发人员为应用程序注册一个或多个重定向URL。授权服务器绝不能重定向到任何其他位置。注册新应用程序包括创建注册表单,以允许开发人员为其应用程序注册重定向URL。
如果攻击者可以在用户到达授权服务器之前操纵重定向URL,则可能导致服务器将用户重定向到恶意服务器,恶意服务器会将授权码发送给攻击者。对于没有client_secret的公共客户端,只需要client_id和授权码就可以获取访问令牌。如果攻击者可以获得授权码,则可以将其交换为公共客户端的访问令牌。这是授权服务器在应用程序注册期间就应该知道应用程序是公共还是私有的另一个重要原因。
有效的重定向网址
在构建表单以允许开发人员注册重定向URL时,您应该对他们输入的URL进行一些基本验证。
已注册的重定向URL可能包含查询字符串参数,但不得在fragment中包含任何内容。如果开发人员尝试注册包含fragment的重定向URL,则注册服务器应拒绝该请求。
请注意,对于原生和移动应用程序,该平台可能允许开发人员注册URL方案myapp://
,然后可以在重定向URL中使用该方案。这意味着授权服务器应允许注册任意URL方案,以支持为原生应用程序注册重定向URL。
按请求自定义
通常,开发人员会认为他们需要能够在每个授权请求上使用不同的重定向URL,并且会尝试更改每个请求的查询字符串参数。这不是重定向URL的预期用途,授权服务器不应该允许这样的URL。服务器应拒绝任何具有与注册URL不完全匹配的重定向URL的授权请求。
如果客户端希望在重定向URL中包含特定于请求的数据,则可以使用“state”参数来存储在重定向用户之后将包括的数据。可以在state参数本身中对数据进行编码,也可以使用state参数作为会话ID来在服务器上存储状态。
原生应用程序的重定向URI
原生应用程序是安装在设备上的客户端,例如桌面应用程序或移动应用程序。在支持与安全性和用户体验相关的原生应用程序时,需要记住一些事项。
授权endpoint通常会将用户重定向回客户端注册的重定向URL。根据平台,应用程序可以声明URL模式,也可以注册启动应用程序的自定义URL方案。例如,iOS应用程序可以注册自定义协议,例如myapp://
,然后使用redirect_uri myapp://callback
。
应用程序声明的https URL重定向
某些平台(从iOS 9开始的Android和iOS)允许应用程序覆盖特定的URL模式以启应用程序而不是Web浏览器。例如,应用程序可以注册https://app.example.com/auth
,只要Web浏览器尝试重定向到该URL,操作系统就会启动应用程序。
如果操作系统支持声明URL,则应使用此方法。这允许操作系统保证应用程序的标识。如果操作系统不支持此操作,则应用程序必须使用自定义URL方案。
自定义URL方案
大多数移动和桌面操作系统允许应用注册自定义URL方案,当从系统浏览器访问具有该方案的URL时,该方案将启动应用程序。
使用此方法,本机应用程序正常启动OAuth流,方法是使用标准授权码参数启动系统浏览器。唯一的区别是重定向URL将是具有应用程序自定义方案的URL。
当授权服务器发送打算将用户重定向到myapp://callback#token=....
的Location header时,手机将启动应用程序,应用程序将能够恢复授权过程,从URL解析访问令牌并在内部存储它。
自定义URL方案命名空间
由于没有集中注册URL方案的方法,因此应用程序必须尽力选择不会相互冲突的URL方案。
您的服务可以通过要求URL方案遵循特定模式来提供帮助,并且只允许开发人员注册与该模式匹配的自定义方案。
例如,Facebook根据应用的客户端ID为每个应用生成一个URL方案。例如,fb00000000://
数字对应于应用程序的客户端ID。这提供了一种生成全局唯一URL方案的合理可靠方法,因为其他应用程序不太可能使用具有此模式的URL方案。
应用程序的另一个选项是将反向域名模式与应用程序发布者控制的域一起使用。这也可以由服务强制执行。
重定向URI验证
有三种情况需要验证重定向网址。
- 当开发人员将重定向URL注册为创建应用程序的一部分时
- 在授权请求中(授权码类型和隐式授权类型)
- 当应用程序交换访问令牌的授权码时
重定向URL注册
如创建应用程序中所述,该服务应允许开发人员在创建应用程序时注册一个或多个重定向URL。重定向URL的唯一限制是它不能包含fragment组件。该服务必须允许开发人员使用自定义URL方案注册重定向URL,以便在某些平台上支持应用程序。
授权请求
当应用程序启动OAuth流程时,它会将用户定向到您服务的授权endpoint。该请求将在URL中包含多个参数,包括重定向URL。
此时,授权服务器必须验证重定向URL,以确保请求中的URL与应用程序的一个已注册URL匹配。请求还将有一个client_id参数,因此服务应该根据该id查找重定向URL。攻击者完全有可能使用一个应用程序的客户端ID和攻击者的重定向URL来创建授权请求,这就是需要注册的原因。
服务应查找URL的完全匹配,并避免仅匹配特定URL的一部分。(如果需要自定义每个请求,客户端可以使用state参数。)简单的字符串匹配就足够了,因为无法根据请求自定义重定向URL。服务器需要做的就是检查请求中的重定向URL是否与开发人员在注册其应用程序时输入的重定向URL相匹配。
如果重定向URL不是已注册的重定向URL之一,则服务器必须立即显示指示此类的错误,而不是重定向用户。这样可以避免将授权服务器用作打开的重定向程序。
授予访问令牌
令牌endpoint时用授权码交换访问令牌的的请求。此请求将包含重定向URL以及授权码。作为安全性的附加度量,服务器应验证此请求中的重定向URL是否与授权码的初始授权请求中包含的重定向URL完全匹配。如果重定向URL不匹配,则服务器会拒绝该请求并显示错误。