category
许多浏览器会阻止第三方cookie,即对浏览器地址栏中显示的域以外的域的请求。这些cookie也称为跨域cookie。此块打破了隐式流,需要新的身份验证模式才能成功登录用户。在Microsoft身份平台中,我们使用带有代码交换验证密钥【Proof Key for Code Exchange】(PKCE)的授权流和刷新令牌,以在第三方cookie被阻止时保持用户登录。
什么是智能跟踪保护(ITP)和隐私沙盒?
Apple Safari有一个默认的隐私保护功能,称为智能跟踪保护(ITP)。Chrome有一个名为“隐私沙盒”的浏览器隐私倡议。这些举措涵盖了浏览器的许多不同的浏览器隐私努力,并具有不同的时间表。这两项工作都会阻止跨域请求的“第三方”cookie,Safari和Brave默认会阻止第三方cookie。Chrome最近宣布,他们将开始默认屏蔽第三方cookie。隐私沙盒包括对分区存储的更改以及第三方cookie阻止。
一种常见的用户跟踪方式是在后台将iframe加载到第三方网站,并使用cookie在互联网上关联用户。不幸的是,这种模式也是在单页应用程序(SPA)中实现隐式流的标准方式。阻止第三方cookie以保护用户隐私的浏览器也可以阻止SPA的功能。
本文中概述的解决方案适用于所有这些浏览器,或任何阻止第三方cookie的地方。
解决方案概述
要继续在SPAs中对用户进行身份验证,应用程序开发人员必须使用授权代码流【 authorization code flow】。在身份验证代码流【auth code flow】中,身份提供者发布一个代码,SPA将代码兑换为访问令牌和刷新令牌。当应用程序需要新的令牌时,它可以使用刷新令牌流来获取新的令牌。适用于JavaScript v2.0及更高版本的Microsoft身份验证库(MSAL)实现了SPA的授权代码流,并进行了少量更新,是MSAL.js 1.x的替代品。有关将SPA从隐式迁移到授权代码流的信息,请参阅迁移指南。
对于Microsoft身份平台,SPAs和本地客户端遵循类似的协议指南:
- PKCE代码挑战【 PKCE code challenge】的使用
- Microsoft身份平台上的SPAs需要PKCE。建议将PKCE用于本机和机密客户端。
- 不使用客户机密【client secret】
SPAs还有两个限制:
- 重定向URI必须标记为spa类型,才能在登录端点上启用CORS。
- 通过授权代码流颁发给spa重定向URI的刷新令牌的生存期为24小时,而不是90天。
图中显示了单页应用程序和安全令牌服务端点之间的OAuth 2授权代码流。
性能和用户体验影响
一些使用隐式流的应用程序尝试在不重定向的情况下登录,方法是使用prompt=none打开登录iframe。在大多数浏览器中,此请求使用当前登录用户的令牌进行响应(假设已授予同意)。这种模式意味着应用程序不需要完整的页面重定向来登录用户,从而提高了性能和用户体验——用户访问网页并已经登录。因为当第三方cookie被阻止时,iframe中的prompt=none不再是一个选项,所以应用程序必须调整其登录模式才能发出授权码。
在没有第三方cookie的情况下,有两种方式可以实现登录:
整页重定向
- 在第一次加载SPA时,如果不存在会话(或者会话已过期),请将用户重定向到登录页面。用户的浏览器访问登录页面,显示包含用户会话的cookie,然后将代码和令牌重定向回片段中的应用程序。
- 重定向确实会导致SPA被加载两次。遵循SPAs缓存的最佳实践,这样应用程序就不会被完整下载两次。
- 考虑在应用程序中设置一个预加载序列,在应用程序完全解包并执行JavaScript负载之前检查登录会话并重定向到登录页面。
弹出窗口
- 如果完整页面重定向的用户体验(UX)不适用于应用程序,请考虑使用弹出窗口来处理身份验证。
- 当弹出窗口在身份验证后完成重定向到应用程序时,重定向处理程序中的代码将在本地存储中存储身份验证代码和令牌,供应用程序使用。MSAL.js和大多数库一样,支持用于身份验证的弹出窗口。
- 浏览器正在减少对弹出窗口的支持,因此它们可能不是最可靠的选择。可能需要用户在创建弹出窗口之前与SPA进行交互,以满足浏览器要求。
苹果公司将弹出式方法描述为一种临时兼容性修复程序,允许原始窗口访问第三方cookie。虽然苹果可能会在未来取消这种权限转移,但这不会影响此处的指导。
在这里,弹出窗口被用作登录页面的第一方导航【first party navigation 】,以便找到会话并提供身份验证代码。这将在未来继续发挥作用。
开发人员可以继续使用prompt=none,期望在第三方cookie被阻止时,他们看到更高的interaction_required错误率。如果在静默令牌获取过程中发生故障,建议始终使用交互式方法回退。
使用iframe
web应用程序中的一种常见模式是使用iframe将一个应用程序嵌入另一个应用中:顶级框架处理对用户的身份验证,iframe中托管的应用程序可以信任用户已登录,使用隐式流【implicit flow】静默地获取令牌。然而,无论浏览器中是否启用或阻止了第三方cookie,这一假设都有几点需要注意。
当第三方cookie被阻止时,静默式令牌获取不再有效-嵌入在iframe中的应用程序必须切换到使用弹出窗口来访问用户的会话,因为它无法导航到嵌入框架内的登录页面。
您可以通过将用户(帐户)提示从父应用程序传递到iframed应用程序,实现iframed和父应用程序之间的单一登录,并使用同源【same-origin】和跨源【 cross-origin】JavaScript脚本API访问。有关更多信息,请参阅在GitHub上的MSAL.js存储库中的iframed应用程序中使用MSAL.js。
浏览器中刷新令牌的安全含义
跨站点脚本(XSS)攻击或受损的JS包可以窃取刷新令牌并远程使用它,直到它过期或被吊销。应用程序开发人员负责降低应用程序跨站点脚本编写的风险。为了最大限度地降低刷新代币被盗的风险,SPAs只发行24小时有效的令牌。24小时后,应用程序必须通过访问登录页面的顶级框架获取新的授权码。
选择这种寿命有限的刷新令牌模式是为了在安全性和降级的用户体验之间取得平衡。如果没有刷新令牌或第三方cookie,当需要新的或额外的令牌时,授权代码流【authorization code flow 】(如OAuth安全性最佳当前实践草案【OAuth security best current practices draft】所建议的)将变得繁重。每次令牌到期时(对于Microsoft身份平台令牌,通常每小时一次),每个令牌都需要一个完整的页面重定向或弹出窗口。
特定于用户类型的缓解措施
并非所有用户和应用程序都会受到第三方cookie的一致影响。在某些情况下,由于架构或设备管理的原因,可以在没有第三方cookie的情况下进行静默调用【silent calls】以续订令牌。
对于托管企业设备场景,某些浏览器和平台组合支持设备条件访问。应用设备标识可以最大限度地减少对第三方cookie的需求,因为身份验证状态可以来自设备而不是浏览器。
对于Azure AD B2C应用程序场景,客户可以设置自定义登录域以匹配应用程序的域。在这种情况下,浏览器不会阻止第三方cookie,因为cookie保留在同一域中(如login.contoso.com到app.contoso.com.)。
没有第三方cookie的Front Channel注销限制
当用户从SPA注销时,MSAL.js建议使用弹出或重定向注销方法。虽然这会清除服务器和浏览器存储中的身份验证会话,但存在这样的风险,即如果无法访问第三方cookie,并非所有联合应用程序都会同时看到注销。这是OpenID Front Channel Logout 1.0规范的已知限制。这对用户意味着,同一用户的其他应用程序的现有访问令牌将继续有效,直到其到期。用户可以在选项卡A中注销应用程序A,但在访问令牌的剩余有效时间内,选项卡B中的应用程序B仍将显示为已登录。当应用程序B的令牌到期并且对服务器进行调用以获得新令牌时,应用程序B从服务器接收会话已到期的响应,并提示用户进行身份验证。
微软的注销页面和互联网隐私最佳实践建议用户在注销应用程序后关闭所有浏览器窗口。
接下来的步骤
有关授权代码流和MSAL.js的更多信息,请参阅:
- 登录 发表评论