菜单
Grafana Cloud Enterprise 版 开源版

配置通用 OAuth 身份验证

Grafana 中有许多可用的身份验证方法,用于验证用户身份。身份验证配置决定了哪些用户可以访问 Grafana 以及他们可以使用哪些方法登录。您还可以配置 Grafana 根据身份验证提供程序集成返回的信息自动更新用户的 Grafana 角色和团队成员身份。

在选择身份验证方法时,重要的是要考虑您当前的身份和访问管理系统以及您所需的特定身份验证和授权功能。有关可用身份验证选项及其支持功能的完整列表,请参阅配置身份验证

Grafana 为以下身份验证提供程序提供 OAuth2 集成

如果您的 OAuth2 提供程序未列出,您可以使用通用 OAuth 身份验证。

本主题介绍如何使用不同方法配置通用 OAuth 身份验证,并包含设置通用 OAuth 的示例使用特定 OAuth2 提供程序。

开始之前

要遵循本指南

  • 确保您知道如何在 OAuth2 提供程序中创建 OAuth2 应用程序。请查阅您的 OAuth2 提供程序的文档以获取更多信息。
  • 确保您的身份提供程序返回与 OpenID UserInfo 兼容的信息,例如 sub Claim。
  • 如果您正在使用刷新令牌,请确保您知道如何与您的 OAuth2 提供程序进行设置。请查阅您的 OAuth2 提供程序的文档以获取更多信息。

注意

如果用户在 Azure AD 中使用的电子邮件地址与其在其他身份验证提供程序(例如 Grafana.com)中使用的电子邮件地址相同,您需要进行额外配置以确保用户正确匹配。请参阅使用相同电子邮件地址通过不同身份提供程序登录文档了解更多信息。

使用 Grafana UI 配置通用 OAuth 身份验证客户端

注意

通过 ssoSettingsAPI 功能开关提供,默认启用。

作为 Grafana 管理员,您可以使用通用 OAuth UI 在 Grafana 中配置通用 OAuth 客户端。为此,导航到管理 > 身份验证 > 通用 OAuth 页面并填写表单。如果您在 Grafana 配置文件中有当前配置,则表单将预填充这些值,否则表单将包含默认值。

填写完表单后,点击保存以保存配置。如果保存成功,Grafana 将应用新配置。

如果您需要将您在 UI 中所做的更改重置为默认值,点击重置。重置更改后,Grafana 将应用 Grafana 配置文件中的配置(如果有任何配置)或默认值。

注意

如果您在启用高可用性模式下运行 Grafana,配置更改可能不会立即应用到所有 Grafana 实例。您可能需要等待几分钟,配置才能传播到所有 Grafana 实例。

请参阅配置选项了解更多信息。

使用 Terraform 提供程序配置通用 OAuth 身份验证客户端

注意

通过 ssoSettingsAPI 功能开关提供,默认启用。自 Terraform 提供程序 v2.12.0 起支持。

terraform
resource "grafana_sso_settings" "generic_sso_settings" {
  provider_name = "generic_oauth"
  oauth2_settings {
    name              = "Auth0"
    auth_url          = "https://<domain>/authorize"
    token_url         = "https://<domain>/oauth/token"
    api_url           = "https://<domain>/userinfo"
    client_id         = "<client id>"
    client_secret     = "<client secret>"
    allow_sign_up     = true
    auto_login        = false
    scopes            = "openid profile email offline_access"
    use_pkce          = true
    use_refresh_token = true
  }
}

请参阅Terraform Registry以获取使用 grafana_sso_settings 资源的完整参考。

使用 Grafana 配置文件配置通用 OAuth 身份验证客户端

确保您可以访问Grafana 配置文件

步骤

要使用通用 OAuth 身份验证将您的 OAuth2 提供程序与 Grafana 集成,请按照以下步骤操作

  1. 在您选择的 OAuth2 提供程序中创建 OAuth2 应用程序。

  2. 将您的 OAuth2 应用的回调 URL 设置为 http://<my_grafana_server_name_or_ip>:<grafana_server_port>/login/generic_oauth

    确保回调 URL 是您通过浏览器访问 Grafana 使用的完整 HTTP 地址,但附加了路径 /login/generic_oauth

    为了使回调 URL 正确,可能需要设置 Grafana 配置文件 [server] 部分中的 root_url 选项。例如,如果您通过代理提供 Grafana 服务。

  3. 请参阅下表更新位于 Grafana 配置文件 [auth.generic_oauth] 部分的字段值

    字段描述
    client_id, client_secret这些值必须与您的 OAuth2 应用的客户端 ID 和客户端 secret 匹配。
    auth_url您的 OAuth2 提供程序的授权端点。
    api_url您的 OAuth2 提供程序的用户信息端点。此端点返回的信息必须与OpenID UserInfo兼容。
    enabled启用通用 OAuth 身份验证。将此值设置为 true

    查看其他通用 OAuth 的列表配置选项,根据需要完成。

  4. 可选:配置刷新令牌

    a. 使用您的 OAuth2 提供程序使用的刷新令牌范围扩展 Grafana 配置文件 [auth.generic_oauth] 部分的 scopes 字段。

    b. 在 Grafana 配置文件 [auth.generic_oauth] 部分中将 use_refresh_token 设置为 true

    c. 如果需要,在提供程序上启用刷新令牌。

  5. 配置角色映射.

  6. 可选:配置团队同步

  7. 重启 Grafana。

    您现在应该在登录页面看到一个通用 OAuth 登录按钮,并且能够使用您的 OAuth2 提供程序登录或注册。

配置登录

Grafana 可以从 OAuth2 ID 令牌或从 OAuth2 UserInfo 端点检索到的用户信息解析用户的登录名。Grafana 按照列出的顺序查找这些来源,直到找到登录名。如果未找到登录名,则用户的登录名设置为用户的电子邮件地址。

请参阅下表,了解根据您的 Oauth2 提供程序如何返回用户登录名进行配置的信息

登录名来源所需配置
OAuth2 ID 令牌的 loginusername 字段。不适用
OAuth2 ID 令牌的另一个字段。设置 login_attribute_path 配置选项。
来自 UserInfo 端点的用户信息中的 loginusername 字段。不适用
来自 UserInfo 端点的用户信息的另一个字段。设置 login_attribute_path 配置选项。

配置显示名称

Grafana 可以从 OAuth2 ID 令牌或从 OAuth2 UserInfo 端点检索到的用户信息解析用户的显示名称。Grafana 按照列出的顺序查找这些来源,直到找到显示名称。如果未找到显示名称,则显示用户的登录名。

请参阅下表,了解根据您的 Oauth2 提供程序如何返回用户名进行配置的信息

显示名称来源所需配置
OAuth2 ID 令牌的 namedisplay_name 字段。不适用
OAuth2 ID 令牌的另一个字段。设置 name_attribute_path 配置选项。
来自 UserInfo 端点的用户信息中的 namedisplay_name 字段。不适用
来自 UserInfo 端点的用户信息的另一个字段。设置 name_attribute_path 配置选项。

配置电子邮件地址

Grafana 可以从 OAuth2 ID 令牌、从 OAuth2 UserInfo 端点检索到的用户信息或 OAuth2 /emails 端点解析用户的电子邮件地址。Grafana 按照列出的顺序查找这些来源,直到找到电子邮件地址。如果未找到电子邮件地址,则用户的电子邮件地址将设置为空字符串。

请参阅下表,了解根据 Oauth2 提供程序如何返回用户电子邮件地址进行配置的信息

电子邮件地址来源所需配置
OAuth2 ID 令牌的 email 字段。不适用
OAuth2 ID 令牌的 attributes 映射。设置 email_attribute_name 配置选项。默认情况下,Grafana 在 email:primary 键下搜索电子邮件。
OAuth2 ID 令牌的 upn 字段。不适用
来自 UserInfo 端点的用户信息中的 email 字段。不适用
来自 UserInfo 端点的用户信息的另一个字段。设置 email_attribute_path 配置选项。
来自 OAuth2 提供程序 /emails 端点中标记为主要的电子邮件地址
(通过将 /emails 附加到 URL 获取)
使用 api_url 配置)
不适用

配置刷新令牌

当用户使用 OAuth2 提供程序登录时,Grafana 会验证访问令牌是否未过期。当访问令牌过期时,Grafana 会使用提供的刷新令牌(如果存在)来获取新的访问令牌。

Grafana 使用刷新令牌获取新的访问令牌,而无需用户再次登录。如果刷新令牌不存在,Grafana 会在访问令牌过期后将用户注销系统。

要配置通用 OAuth 使用刷新令牌,请将 use_refresh_token 配置选项设置为 true,并在需要时执行以下一个或两个步骤

  1. 使用附加范围扩展 Grafana 配置文件 [auth.generic_oauth] 部分的 scopes 字段。
  2. 在提供程序上启用刷新令牌。

注意

accessTokenExpirationCheck 功能开关已在 Grafana v10.3.0 中移除,而是将使用 use_refresh_token 配置值来配置刷新令牌获取和访问令牌过期检查。

配置角色映射

除非启用 skip_org_role_sync 选项,否则用户的角色将设置为用户登录时从身份验证提供程序检索到的角色。

使用JMESPath表达式从 role_attribute_path 配置选项中检索用户的角色。要映射服务器管理员角色,请使用 allow_assign_grafana_admin 配置选项。请参阅配置选项了解更多信息。

如果未找到有效角色,则为用户分配由auto_assign_org_role 选项指定的角色。您可以通过设置 role_attribute_strict = true 来禁用此默认角色分配。如果在评估 role_attribute_pathorg_mapping 表达式后未返回角色或返回无效角色,此设置将拒绝用户访问。

您可以使用 org_attribute_pathorg_mapping 配置选项将用户分配到组织并指定其角色。有关更多信息,请参阅组织角色映射示例。如果同时指定了组织角色映射 (org_mapping) 和常规角色映射 (role_attribute_path),则用户将获得两个映射角色中的最高者。

为了方便配置正确的 JMESPath 表达式,请访问JMESPath使用自定义负载测试和评估表达式。

角色映射示例

本节包含用于角色映射的 JMESPath 表达式示例。

映射用户组织角色

在此示例中,用户被授予 Editor 角色。分配的角色基于属性 role 的值,该值必须是有效的 Grafana 角色,例如 AdminEditorViewerNone

负载

json
{
    ...
    "role": "Editor",
    ...
}

配置

bash
role_attribute_path = role

在下面更复杂的示例中,用户被授予 Admin 角色。这是因为他们是 OAuth2 提供程序中 admin 组的成员。如果用户是 editor 组的成员,他们将被授予 Editor 角色,否则为 Viewer

负载

json
{
    ...
    "groups": [
        "engineer",
        "admin",
    ],
    ...
}

配置

bash
role_attribute_path = contains(groups[*], 'admin') && 'Admin' || contains(groups[*], 'editor') && 'Editor' || 'Viewer'
映射服务器管理员角色

在以下示例中,用户被授予 Grafana 服务器管理员角色。

负载

json
{
    ...
    "roles": [
        "admin",
    ],
    ...
}

配置

ini
role_attribute_path = contains(roles[*], 'admin') && 'GrafanaAdmin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'
allow_assign_grafana_admin = true
将一个角色映射给所有用户

在此示例中,无论从身份提供程序接收到的用户信息如何,所有用户都将被分配 Viewer 角色。

配置

ini
role_attribute_path = "'Viewer'"
skip_org_role_sync = false

组织角色映射示例

在此示例中,用户在 org_foo 组织中被授予 Viewer 角色,在 org_barorg_baz 组织中被授予 Editor 角色。

如果用户是 admin 组的成员,他们将被授予 Grafana 服务器管理员角色。

负载

json
{
  "roles": ["org_foo", "org_bar", "another_org"]
}

配置

ini
role_attribute_path = contains(roles[*], 'admin') && 'GrafanaAdmin' || 'None'
allow_assign_grafana_admin = true
org_attribute_path = roles
org_mapping = org_foo:org_foo:Viewer org_bar:org_bar:Editor *:org_baz:Editor

配置团队同步

注意

可在Grafana Enterprise 版Grafana Cloud中可用。

通过使用团队同步,您可以将您的 OAuth2 组链接到 Grafana 中的团队。这将自动将用户分配到相应的团队。每个用户的团队会在用户登录时同步。

通用 OAuth 组可以通过组 ID 引用,例如 8bab1c86-8fba-33e5-2089-1d1c80ec267dmyteam。有关使用 groups_attribute_path 配置选项配置 Grafana 中的 OAuth2 组的信息,请参阅配置选项

要了解有关团队同步的更多信息,请参阅配置团队同步

团队同步示例

配置

bash
groups_attribute_path = groups

负载

json
{
    ...
    "groups": [
        "engineers",
        "analysts",
    ],
    ...
}

配置选项

下表列出了各种通用 OAuth 配置选项。您可以将这些选项作为环境变量应用,类似于 Grafana 中的任何其他配置。有关更多信息,请参阅使用环境变量覆盖配置

注意

如果配置选项需要包含冒号的 JMESPath 表达式,请将整个表达式用引号括起来,以防止解析错误。例如 role_attribute_path: "role:view"

设置必需Cloud 版支持描述默认值
enabled启用通用 OAuth 身份验证。false
name在 Grafana 用户界面中引用通用 OAuth 身份验证的名称。OAuth
icon在 Grafana 用户界面中用于通用 OAuth 身份验证的图标。signin
client_id您的 OAuth2 应用提供的客户端 ID。
client_secret您的 OAuth2 应用提供的客户端 secret。
auth_url您的 OAuth2 提供程序的授权端点。
token_url用于获取 OAuth2 访问令牌的端点。
api_url用于获取与OpenID UserInfo兼容的用户信息兼容的端点。
auth_style在从 OAuth2 提供程序请求 ID 令牌时使用的OAuth2 AuthStyle的名称。它决定了如何将 client_idclient_secret 发送到 Oauth2 提供程序。可用值包括 AutoDetectInParamsInHeaderAutoDetect
scopes逗号或空格分隔的 OAuth2 范围列表。user:email
empty_scopes设置为 true 以在身份验证期间使用空范围。false
allow_sign_up通过通用 OAuth 登录控制 Grafana 用户创建。如果设置为 false,则只有现有的 Grafana 用户才能通过通用 OAuth 登录。true
auto_login设置为 true 以启用用户绕过登录屏幕并自动登录。如果您配置多个身份验证提供程序使用自动登录,此设置将被忽略。false
id_token_attribute_name用于从返回的 OAuth2 令牌中提取 ID 令牌的键名称。id_token
login_attribute_pathJMESPath表达式,用于从用户 ID 令牌查找用户登录名。有关如何检索用户登录名的更多信息,请参阅配置登录
name_attribute_pathJMESPath表达式,用于从用户 ID 令牌查找用户名。此名称将用作用户的显示名称。有关如何检索用户显示名称的更多信息,请参阅配置显示名称
email_attribute_pathJMESPath表达式,用于从用户信息查找用户电子邮件地址。有关如何检索用户电子邮件地址的更多信息,请参阅配置电子邮件地址
email_attribute_name用于在 OAuth2 ID 令牌的 attributes 映射中查找用户电子邮件地址的键名称。有关如何检索用户电子邮件地址的更多信息,请参阅配置电子邮件地址email:primary
role_attribute_pathJMESPath表达式,用于查找 Grafana 角色。Grafana 将首先使用 OAuth2 ID 令牌评估表达式。如果未找到角色,将使用从 UserInfo 端点获取的用户信息评估表达式。评估结果应为有效的 Grafana 角色(NoneViewerEditorAdminGrafanaAdmin)。有关用户角色映射的更多信息,请参阅配置角色映射
role_attribute_strict设置为 true,如果在评估 role_attribute_pathorg_mapping 后无法提取 Grafana 组织角色,则拒绝用户登录。有关用户角色映射的更多信息,请参阅配置角色映射false
skip_org_role_sync设置为 true 以停止自动同步用户角色。这将允许您在 Grafana 中手动为用户设置组织角色。false
org_attribute_pathJMESPath表达式,用于查找 Grafana 组织到角色的映射。Grafana 将首先使用 OAuth2 ID 令牌评估表达式。如果没有返回值,表达式将使用从 UserInfo 端点获取的用户信息进行评估。评估结果将根据 org_mapping 映射到组织角色。有关组织到角色映射的更多信息,请参阅组织角色映射示例
org_mapping逗号或空格分隔的 <ExternalOrgName>:<OrgIdOrName>:<Role> 映射列表。值可以是 * 表示“所有用户”。Role 是可选的,可以具有以下值:NoneViewerEditorAdmin。有关外部组织到角色映射的更多信息,请参阅组织角色映射示例
allow_assign_grafana_admin设置为 true 以启用 Grafana 服务器管理员角色的自动同步。如果此选项设置为 true 且评估用户 role_attribute_path 的结果是 GrafanaAdmin,Grafana 会授予用户服务器管理员权限和组织管理员角色。如果此选项设置为 false 且评估用户 role_attribute_path 的结果是 GrafanaAdmin,Grafana 仅授予用户组织管理员角色。有关用户角色映射的更多信息,请参阅配置角色映射false
groups_attribute_pathJMESPath 表达式,用于查找用户组。Grafana 将首先使用 OAuth2 ID 令牌评估该表达式。如果未找到任何组,则将使用从 UserInfo endpoint 获取的用户信息评估该表达式。评估结果应为一个字符串数组,包含用户所属的组。
allowed_groups逗号或空格分隔的组列表。用户必须是至少一个组的成员才能登录。如果配置了 allowed_groups,则还必须配置 groups_attribute_path
allowed_organizations逗号或空格分隔的组织列表。用户必须是至少一个组织的成员才能登录。
allowed_domains逗号或空格分隔的域列表。用户必须属于至少一个域才能登录。
team_ids团队 ID 的字符串列表。如果设置,用户必须是给定团队中一个的成员才能登录。如果配置了 team_ids,则还必须配置 teams_urlteam_ids_attribute_path
team_ids_attribute_path用于在 teams_url 端点返回的结果中查找 Grafana 团队 ID 的 JMESPath 表达式。
teams_url用于查询团队 ID 的 URL。如果未设置,默认值为 /teams。如果配置了 teams_url,则还必须配置 team_ids_attribute_path
tls_skip_verify_insecure如果设置为 true,客户端接受服务器提供的任何证书以及该证书中的任何主机名。仅应在测试时使用此项,因为此模式使 SSL/TLS 容易受到中间人攻击。false
tls_client_cert证书的路径。
tls_client_key密钥的路径。
tls_client_ca受信任的证书颁发机构列表的路径。
use_pkce设置为 true 以使用 Proof Key for Code Exchange (PKCE)。Grafana 使用基于 SHA256 的 S256 质询方法和 128 字节(base64url 编码)的代码验证器。false
use_refresh_token设置为 true 以使用刷新令牌并检查访问令牌是否过期。false
signout_redirect_url用户注销后重定向到的 URL。

配置通用 OAuth 的示例

本节包含配置通用 OAuth 集成的示例。

使用 Descope 配置 OAuth2

要使用 Descope 配置通用 OAuth 身份验证,请按照以下步骤操作

  1. 在此处创建 Descope 项目,然后按照入门向导配置您的身份验证。如果您已经设置了 Descope 项目,可以跳过此步骤。

  2. 如果您希望使用除 Sign Up or In 之外的流程,请转到控制台中的 IdP Applications 菜单,选择您的 IdP 应用程序。然后修改 Flow Hosting URL 查询参数 ?flow=sign-up-or-in 来更改您希望使用的流程 ID。

  3. 单击 保存

  4. 使用 Settings 标签页中的值更新 Grafana 配置文件的 [auth.generic_oauth] 部分

    注意

    您可以在项目设置下获取您的客户端 ID (Descope 项目 ID)。您的客户端密钥 (Descope 访问密钥) 可以在访问密钥下生成。

    bash
    [auth.generic_oauth]
    enabled = true
    allow_sign_up = true
    auto_login = false
    team_ids =
    allowed_organizations =
    name = Descope
    client_id = <Descope Project ID>
    client_secret = <Descope Access Key>
    scopes = openid profile email descope.claims descope.custom_claims
    auth_url = https://api.descope.com/oauth2/v1/authorize
    token_url = https://api.descope.com/oauth2/v1/token
    api_url = https://api.descope.com/oauth2/v1/userinfo
    use_pkce = true
    use_refresh_token = true

使用 Auth0 配置 OAuth2

注意

Grafana 目前不支持 Auth0 的“audience”功能。有关角色和权限,可在此处找到可用选项说明。

要使用 Auth0 配置通用 OAuth 身份验证,请按照以下步骤操作

  1. 使用以下参数创建 Auth0 应用程序

    • 名称: Grafana
    • 类型: Regular Web Application
  2. 转到应用程序的 Settings 标签页,并将 Allowed Callback URLs 设置为 https://<grafana domain>/login/generic_oauth

  3. 单击 保存更改

  4. 使用 Settings 标签页中的值更新 Grafana 配置文件的 [auth.generic_oauth] 部分

    bash
    [auth.generic_oauth]
    enabled = true
    allow_sign_up = true
    auto_login = false
    team_ids =
    allowed_organizations =
    name = Auth0
    client_id = <client id>
    client_secret = <client secret>
    scopes = openid profile email offline_access
    auth_url = https://<domain>/authorize
    token_url = https://<domain>/oauth/token
    api_url = https://<domain>/userinfo
    use_pkce = true
    use_refresh_token = true

使用 Bitbucket 配置 OAuth2

要使用 Bitbucket 配置通用 OAuth 身份验证,请按照以下步骤操作

  1. 在 BitBucket 中导航至 Settings > Workspace setting > OAuth consumers

  2. 通过选择 Add consumer 并使用以下参数创建应用程序

    • 允许的回调 URL: https://<grafana domain>/login/generic_oauth
  3. 单击 保存

  4. 使用消费者描述中的 KeySecret 值更新 Grafana 配置文件的 [auth.generic_oauth] 部分

    bash
    [auth.generic_oauth]
    name = BitBucket
    enabled = true
    allow_sign_up = true
    auto_login = false
    client_id = <client key>
    client_secret = <client secret>
    scopes = account email
    auth_url = https://bitbucket.org/site/oauth2/authorize
    token_url = https://bitbucket.org/site/oauth2/access_token
    api_url = https://api.bitbucket.org/2.0/user
    teams_url = https://api.bitbucket.org/2.0/user/permissions/workspaces
    team_ids_attribute_path = values[*].workspace.slug
    team_ids =
    allowed_organizations =
    use_refresh_token = true

默认情况下,对于 Authorization Code Grant,响应中会包含刷新令牌。

使用 OneLogin 配置 OAuth2

要使用 OneLogin 配置通用 OAuth 身份验证,请按照以下步骤操作

  1. 在 OneLogin 中创建具有以下设置的新自定义连接器

    • 名称: Grafana
    • 登录方法: OpenID Connect
    • 重定向 URI: https://<grafana domain>/login/generic_oauth
    • 签名算法: RS256
    • 登录 URL: https://<grafana domain>/login/generic_oauth
  2. 将应用程序添加到 Grafana 连接器

    • 显示名称: Grafana
  3. 使用应用详细信息页面的 SSO 标签页中的客户端 ID 和客户端密钥更新 Grafana 配置文件的 [auth.generic_oauth] 部分

    您的 OneLogin 域将与您用于访问 OneLogin 的 URL 匹配。

    bash
    [auth.generic_oauth]
    name = OneLogin
    enabled = true
    allow_sign_up = true
    auto_login = false
    client_id = <client id>
    client_secret = <client secret>
    scopes = openid email name
    auth_url = https://<onelogin domain>.onelogin.com/oidc/2/auth
    token_url = https://<onelogin domain>.onelogin.com/oidc/2/token
    api_url = https://<onelogin domain>.onelogin.com/oidc/2/me
    team_ids =
    allowed_organizations =

使用 Dex 配置 OAuth2

要使用 Dex IdP 配置通用 OAuth 身份验证,请按照以下步骤操作

  1. 在 Dex 配置 YAML 文件中将 Grafana 添加为客户端

    yaml
    staticClients:
      - id: <client id>
        name: Grafana
        secret: <client secret>
        redirectURIs:
          - 'https://<grafana domain>/login/generic_oauth'

    注意

    与许多其他 OAuth2 提供商不同,Dex 不提供 <client secret>。相反,可以使用例如 openssl rand -hex 20 生成一个密钥。

  2. 更新 Grafana 配置的 [auth.generic_oauth] 部分

    bash
    [auth.generic_oauth]
    name = Dex
    enabled = true
    client_id = <client id>
    client_secret = <client secret>
    scopes = openid email profile groups offline_access
    auth_url = https://<dex base uri>/auth
    token_url = https://<dex base uri>/token
    api_url = https://<dex base uri>/userinfo

    <dex base uri> 对应于 Dex 中的 issuer: 配置(例如,Dex 域,可能包含路径,如 /dex)。使用刷新令牌时需要 offline_access 作用域。