菜单
企业版 开源版

配置 JWT 身份验证

您可以配置 Grafana 接受 HTTP 头中提供的 JWT 令牌。可以使用以下任何方式验证令牌:

  • PEM 编码的密钥文件
  • 本地文件中的 JSON Web Key Set (JWKS)
  • 由配置的 JWKS 端点提供的 JWKS

这种身份验证方法适用于与其他使用 JWKS 但无法直接与 Grafana 集成的系统集成,或者您想在嵌入 Grafana 的应用程序中使用透传身份验证。

注意

Grafana 当前不支持刷新令牌。

启用 JWT

要使用 JWT 身份验证,

  1. 主配置文件中启用 JWT。
  2. 指定包含令牌的 HTTP 头名称。
ini
[auth.jwt]
# By default, auth.jwt is disabled.
enabled = true

# HTTP header to look into to get a JWT token.
header_name = X-JWT-Assertion

配置登录 Claim

为了识别用户,需要选择一些 Claim 作为登录信息。名为 "sub" 的 Subject Claim 是必需的,需要标识 JWT 的主体。

通常,名为 "sub" 的 Subject Claim 会用作登录名,但也可以将其设置为某些应用程序特定的 Claim。

ini
# [auth.jwt]
# ...

# Specify a claim to use as a username to sign in.
username_claim = sub

# Specify a claim to use as an email to sign in.
email_claim = sub

# auto-create users if they are not already matched
# auto_sign_up = true

如果启用了 auto_sign_up,则 sub Claim 用作“外部身份验证 ID”。如果存在 name Claim,则用作用户的全名。

此外,如果登录用户名或电子邮件 Claim 嵌套在 JWT 结构中,您可以使用 JMESPath 语法,通过 username_attribute_pathemail_attribute_path 配置选项指定属性路径。

JWT 结构示例。

json
{
  "user": {
    "UID": "1234567890",
    "name": "John Doe",
    "username": "johndoe",
    "emails": ["personal@email.com", "professional@email.com"]
  }
}
ini
# [auth.jwt]
# ...

# Specify a nested attribute to use as a username to sign in.
username_attribute_path = user.username # user's login is johndoe

# Specify a nested attribute to use as an email to sign in.
email_attribute_path = user.emails[1] # user's email is professional@email.com

Iframe 嵌入

如果您想在 iframe 中嵌入 Grafana 并保持用户身份和角色检查,可以使用 JWT 身份验证来认证 iframe。

注意

对于 Grafana Cloud 或不需要验证查看者身份的场景,可以嵌入共享仪表盘

在这种场景下,您需要配置 Grafana 接受 HTTP 头中提供的 JWT,并且反向代理应该重写对 Grafana 实例的请求,以便在请求头中包含 JWT。

注意

为了使嵌入功能正常工作,您必须在安全部分启用 allow_embedding。此设置在 Grafana Cloud 中不可用。

在无法重写请求头的场景下,您可以使用 URL 登录代替。

URL 登录

url_login 允许 Grafana 在 URL 查询参数 auth_token 中查找 JWT 并将其用作身份验证令牌。

注意

在设置此项之前,您需要启用 JWT。请参阅启用 JWT

警告

如果服务器未使用基于 TLS 的 HTTP,这可能导致 JWT 在日志中暴露,并可能导致会话劫持。

ini
# [auth.jwt]
# ...
url_login = true # enable JWT authentication in the URL

使用 JWT URL 身份验证访问 Grafana 的 URL 示例如下:

http://env.grafana.local/d/RciOKLR4z/board-identifier?orgId=1&kiosk&auth_token=eyJhbxxxxxxxxxxxxx

使用此身份验证方法的示例仓库可在 grafana-iframe-oauth-sample 找到。

签名验证

JSON Web Token 的完整性需要验证,因此使用加密签名来实现此目的。我们期望每个令牌都必须使用某个已知加密密钥进行签名。

您有多种选项来指定密钥的位置。

使用从 HTTPS 端点加载的 JSON Web Key Set 验证令牌

有关 JWKS 端点的更多信息,请参阅 Auth0 文档

ini
# [auth.jwt]
# ...

jwk_set_url = https://your-auth-provider.example.com/.well-known/jwks.json

# Cache TTL for data loaded from http endpoint.
cache_ttl = 60m

注意

如果 JWKS 端点包含缓存控制头且值小于配置的 cache_ttl,则使用缓存控制头的值代替。如果未设置 cache_ttl,则不进行缓存。忽略 no-storeno-cache 缓存控制头。

使用从 JSON 文件加载的 JSON Web Key Set 验证令牌

密钥集格式与 JWKS 端点相同,但位于磁盘上。

ini
jwk_set_file = /path/to/jwks.json

使用从 PEM 编码文件加载的单个密钥验证令牌

采用 PKIX、PKCS #1、PKCS #8 或 SEC 1 格式的 PEM 编码密钥文件。

ini
key_file = /path/to/key.pem

如果 JWT 令牌的头部指定了 kid (Key ID),则必须使用 key_id 配置选项设置 Key ID。

ini
key_id = my-key-id

验证 Claims

默认情况下,仅验证 "exp""nbf""iat" Claims。

考虑使用 expect_claims 配置选项验证其他 Claims 是否符合您的预期。令牌 Claims 必须与此处设置的值完全匹配。

ini
# This can be seen as a required "subset" of a JWT Claims Set.
expect_claims = {"iss": "https://your-token-issuer", "your-custom-claim": "foo"}

角色

Grafana 使用通过 role_attribute_path 配置选项指定的 JMESPath 检查是否存在角色。JMESPath 应用于 JWT 令牌 Claims。评估 role_attribute_path JMESPath 表达式后的结果应该是一个有效的 Grafana 角色,例如 NoneViewerEditorAdmin

要将角色分配给特定组织,在向 Grafana 发送 API 请求时,请将 X-Grafana-Org-Id 头与您的 JWT 一起包含。要了解有关此头的更多信息,请参阅文档

配置角色映射

除非启用了 skip_org_role_sync 选项,否则用户的角色将被设置为从 JWT 中检索到的角色。

用户的角色是使用从 role_attribute_path 配置选项中获得的 JMESPath 表达式检索的。要映射服务器管理员角色,请使用 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,使用自定义 payload 测试和评估表达式。

基本示例

在以下示例中,用户在身份验证时将获得 Editor 角色。如果角色是有效的 Grafana 角色(即 NoneViewerEditorAdmin),则属性 role 的值将成为结果角色。

载荷

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

配置

ini
role_attribute_path = role

高级示例

在以下示例中,用户在身份验证时将获得 Admin 角色,因为他拥有 admin 角色。如果用户拥有 editor 角色,则将获得 Editor 角色,否则为 Viewer

载荷

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

配置

ini
role_attribute_path = contains(info.roles[*], 'admin') && 'Admin' || contains(info.roles[*], 'editor') && 'Editor' || 'Viewer'

组织角色映射示例

在以下示例中,用户被授予了 org_foo 组织中的 Viewer 角色,以及 org_barorg_baz 组织中的 Editor 角色。

载荷

json
{
    ...
    "info": {
        ...
        "orgs": [
            "engineer",
            "admin",
        ],
        ...
    },
    ...
}

配置

ini
org_attribute_path = info.orgs
org_mapping = engineer:org_foo:Viewer admin:org_bar:Editor *:org_baz:Editor

Grafana 管理员角色

如果 role_attribute_path 属性返回 GrafanaAdmin 角色,则默认情况下不分配 Grafana Admin 角色,而是分配 Admin 角色。要允许分配 Grafana Admin 角色,请设置 allow_assign_grafana_admin = true

跳过组织角色映射

要在通过 JWT 登录时跳过角色和权限的分配,并通过用户界面等其他机制处理它们,我们可以使用以下配置跳过组织角色同步。

ini
[auth.jwt]
# ...

skip_org_role_sync = true