Skip to main content

OAuth 和 OpenID Connect

本节介绍 Backstage 如何允许插件代表用户请求 OAuth 访问令牌和 OpenID Connect ID 令牌,以用于对各种第三方 API 的认证。

摘要

在某些情况下,用户希望对需要通过 OAuth 授权的第三方服务执行操作。 Backstage提供了标准化的实用 APIGoogleAuthApiBackstage 还包括这些应用程序接口的一套实现方法,这些实现方法与认证后端插件,提供基于弹出式窗口的 OAuth 流程。

背景

OAuth 中的访问控制是通过范围来实现的,范围是授予应用程序的权限列表。 OAuth 服务可以发出与特定范围(如查看个人资料信息、读取和/或写入服务中的用户数据)绑定的访问令牌。 每个 OAuth 提供商都有特定的范围格式和处理方式,可用的范围通常可在描述该提供商的认证解决方案的文档中找到,例如developers.google.com/identity/protocols/oauth2/scopes.

作为使用 OAuth 提供商登录的一部分,用户需要同意登录本身和应用程序请求使用的范围集。 具体做法是加载 OAuth 提供商提供的页面,用户可以在该页面上选择要登录的账户,并接受或拒绝请求。 如果用户接受登录请求,则会发出一个令牌,令牌的任何持有者都可以使用该令牌向第三方服务发出经过验证的请求。

@backstage/core-app-api 和 auth-backend 中的 OAuth

Backstage 中默认的 OAuth 实现基于 OAuth 服务器端离线访问流程,这意味着它使用后端作为助手,以便进行凭证交易。 这种流程的一个好处是,它不需要使用第三方 cookie,在多种浏览器和隐私浏览插件、严格的安全设置等选择上都很稳健。

该实现还使用了基于弹出窗口的流程,即在应用程序打开的新弹出窗口中处理身份验证请求。 通过使用基于弹出窗口的流程,可以在应用程序中的任何位置请求身份验证,而无需重定向。 因此,无需预先请求所有作用域,也无需通过重定向中断应用程序,更无需迫使插件作者在重定向后恢复状态。 总之,这使得在插件内进行身份验证请求变得更加容易。

OAuth 流程

下面描述了由认证后端DefaultAuthConnector@backstage/core-app-api.

组件和应用程序接口可以向任何可用的 Auth 提供商请求访问或 ID 标记。 如果已经存在一个缓存的新标记(至少)覆盖了所请求的范围,则会立即返回。 如果 OAuth 提供商实现了标记刷新,则在没有可用会话的情况下,该检查也会触发标记刷新尝试。

如果请求新的范围,或者用户尚未登录该提供商,则会显示一个对话框,通知用户需要登录指定的提供商。 如果用户同意继续,则会打开一个单独的弹出窗口,执行整个同意流程。

弹出窗口指向/start中认证提供程序的auth-backend插件,然后重定向到提供商的 OAuth 同意屏幕。 同意屏幕由 OAuth 提供商控制,会提示用户使用账户登录,并可能审查所请求的范围集。 如果登录请求被接受,弹出窗口将重定向到/handler/frame重定向 URL 将包含一个短期授权代码,该代码由后端程序获取,并通过调用 OAuth 提供商交换长期令牌。 然后,访问令牌和可能的 ID 令牌将通过以下方式交还给Backstage主页面postMessage如果 OAuth 提供程序实现了离线刷新,刷新令牌将被存储在一个只适用于特定提供程序的 HTTP cookie 中。auth-backend插件。

为了防止某些攻击,上述流程还包括一个简单的 nonce 检查和一个轻量级 CSRF 保护标头。 进行 nonce 检查是为了防止攻击者诱骗用户使用攻击者选择的账户登录以收集数据的攻击。 在流程的第一部分,弹出窗口被引导至/start重定向处理程序会检查 cookie 和 OAuth 状态中收到的 nonces,如果它们无效,验证尝试就会失败。/refresh/logout端点,只需检查是否存在一个X-Requested-With

的目标原点postMessage也是保证流量安全的重要因素。 每个认证提供商和环境都要将其配置为单一值。 如果没有单一的配置源,任何页面都可能打开弹出窗口并请求访问令牌。

序列图

下图直观展示了上一节所述的流程。

Sequence Diagram