配置 JWT 身份验证
您可以配置 Grafana 接受 HTTP 头中提供的 JWT 令牌。可以使用以下任何方式验证令牌:
- PEM 编码的密钥文件
- 本地文件中的 JSON Web Key Set (JWKS)
- 由配置的 JWKS 端点提供的 JWKS
这种身份验证方法适用于与其他使用 JWKS 但无法直接与 Grafana 集成的系统集成,或者您想在嵌入 Grafana 的应用程序中使用透传身份验证。
注意
Grafana 当前不支持刷新令牌。
启用 JWT
要使用 JWT 身份验证,
- 在主配置文件中启用 JWT。
- 指定包含令牌的 HTTP 头名称。
[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。
# [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_path
和 email_attribute_path
配置选项指定属性路径。
JWT 结构示例。
{
"user": {
"UID": "1234567890",
"name": "John Doe",
"username": "johndoe",
"emails": ["personal@email.com", "professional@email.com"]
}
}
# [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 在日志中暴露,并可能导致会话劫持。
# [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 文档。
# [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-store
和no-cache
缓存控制头。
使用从 JSON 文件加载的 JSON Web Key Set 验证令牌
密钥集格式与 JWKS 端点相同,但位于磁盘上。
jwk_set_file = /path/to/jwks.json
使用从 PEM 编码文件加载的单个密钥验证令牌
采用 PKIX、PKCS #1、PKCS #8 或 SEC 1 格式的 PEM 编码密钥文件。
key_file = /path/to/key.pem
如果 JWT 令牌的头部指定了 kid
(Key ID),则必须使用 key_id
配置选项设置 Key ID。
key_id = my-key-id
验证 Claims
默认情况下,仅验证 "exp"
、"nbf"
和 "iat"
Claims。
考虑使用 expect_claims
配置选项验证其他 Claims 是否符合您的预期。令牌 Claims 必须与此处设置的值完全匹配。
# 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 角色,例如 None
、Viewer
、Editor
或 Admin
。
要将角色分配给特定组织,在向 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_path
和 org_mapping
表达式后,如果没有返回角色或返回了无效角色时,会拒绝用户访问。
您可以使用 org_attribute_path
和 org_mapping
配置选项将用户分配到组织并指定他们的角色。更多信息,请参阅组织角色映射示例。如果同时指定了组织角色映射(org_mapping
)和常规角色映射(role_attribute_path
),则用户将获得两个映射角色中权限最高的角色。
为了方便配置正确的 JMESPath 表达式,请访问 JMESPath,使用自定义 payload 测试和评估表达式。
基本示例
在以下示例中,用户在身份验证时将获得 Editor
角色。如果角色是有效的 Grafana 角色(即 None
、Viewer
、Editor
或 Admin
),则属性 role
的值将成为结果角色。
载荷
{
...
"role": "Editor",
...
}
配置
role_attribute_path = role
高级示例
在以下示例中,用户在身份验证时将获得 Admin
角色,因为他拥有 admin
角色。如果用户拥有 editor
角色,则将获得 Editor
角色,否则为 Viewer
。
载荷
{
...
"info": {
...
"roles": [
"engineer",
"admin",
],
...
},
...
}
配置
role_attribute_path = contains(info.roles[*], 'admin') && 'Admin' || contains(info.roles[*], 'editor') && 'Editor' || 'Viewer'
组织角色映射示例
在以下示例中,用户被授予了 org_foo
组织中的 Viewer
角色,以及 org_bar
和 org_baz
组织中的 Editor
角色。
载荷
{
...
"info": {
...
"orgs": [
"engineer",
"admin",
],
...
},
...
}
配置
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 登录时跳过角色和权限的分配,并通过用户界面等其他机制处理它们,我们可以使用以下配置跳过组织角色同步。
[auth.jwt]
# ...
skip_org_role_sync = true