自建 grafana 使用 JWT 进行用户认证和授权

自建 grafana 使用 JWT 进行用户认证和授权

在 Kubernetes 上自建 Grafana 时,除了基本的用户名密码认证外,JWT(JSON Web Token)提供了一种无状态的、可集成的认证方式——特别适合与现有身份提供商(IdP)对接,或实现免登录的嵌入式访问场景。本文记录了在 kube-prometheus 栈中为 Grafana 配置 JWT 认证的完整流程。

前置条件

  • 已有基于 kube-prometheus 部署的 Grafana

  • 熟悉 Kubernetes ConfigMap、Secret、Deployment 的基本操作

  • 了解 JWT 的基本概念(Header、Payload、Signature)

整体思路

配置分为三步:

  1. 生成 JWKS(JSON Web Key Set) 并以 ConfigMap 形式注入 Pod

  2. 修改 Deployment 挂载 JWKS 文件

  3. 在 Grafana 配置中启用 JWT 认证


第一步:生成 JWKS 并创建 ConfigMap

访问 mkjwk.org 生成 JWKS 密钥对。根据需求选择算法(本文以 HS256 为例),生成后会得到包含 ktykidkalg 等字段的 JSON。

⚠️ 安全提示k 字段即为签名密钥,务必妥善保管,切勿提交到公开仓库。下文中的密钥值已做脱敏处理,请替换为你自己生成的值。

生成的 JWKS 结构如下:

{
    "keys": [
        {
            "kty": "oct",
            "use": "sig",
            "kid": "<YOUR_KEY_ID>",
            "k": "<YOUR_SECRET_KEY>",
            "alg": "HS256"
        }
    ]
}

将此内容写入 Kubernetes ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-jwt-config
  namespace: monitoring
data:
  jwks.json: |
    {
      "keys": [
        {
          "kty": "oct",
          "use": "sig",
          "kid": "<YOUR_KEY_ID>",
          "k": "<YOUR_SECRET_KEY>",
          "alg": "HS256"
        }
      ]
    }

第二步:在 Deployment 中挂载 JWKS 文件

编辑 grafana-deployment.yaml,需要做两处修改:

2.1 添加 volumeMount

在容器的 volumeMounts 列表末尾追加:

volumeMounts:
  # ... 其他挂载项 ...
  - mountPath: /etc/grafana/jwt
    name: grafana-jwt-config
    readOnly: true    # JWKS 只需读取即可

2.2 添加 volume

在 Pod 的 volumes 列表末尾追加:

volumes:
  # ... 其他卷配置 ...
  - configMap:
      name: grafana-jwt-config
    name: grafana-jwt-config

💡 提示:JWKS 文件为只读配置,建议将 readOnly 设为 true,遵循最小权限原则。


第三步:启用 JWT 鉴权

编辑 grafana-config.yaml(类型为 Secret),在 grafana.ini 中新增 [auth.jwt] 段:

apiVersion: v1
kind: Secret
metadata:
  labels:
    app.kubernetes.io/component: grafana
    app.kubernetes.io/name: grafana
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: <YOUR_GRAFANA_VERSION>
  name: grafana-config
  namespace: monitoring
stringData:
  grafana.ini: |
    [date_formats]
    default_timezone = UTC

    [auth.jwt]
    enabled = true
    header_name = X-JWT-Assertion
    username_claim = sub
    email_claim = sub
    auto_sign_up = true
    username_attribute_path = user.username
    url_login = true
    jwk_set_file = /etc/grafana/jwt/jwks.json
type: Opaque

各配置项说明:

参数

说明

header_name

X-JWT-Assertion

Grafana 从此 HTTP Header 中读取 JWT

username_claim

sub

从 JWT Payload 中取 sub 字段作为用户名

email_claim

sub

从 JWT Payload 中取 sub 字段作为邮箱

auto_sign_up

true

首次 JWT 登录时自动创建 Grafana 用户

url_login

true

允许通过 URL 参数 auth_token 传递 JWT

jwk_set_file

/etc/grafana/jwt/jwks.json

JWKS 文件的 Pod 内路径


应用配置

按顺序执行,确保 ConfigMap 先于 Deployment 生效:

kubectl apply -f grafana-jwt-config.yaml
kubectl apply -f grafana-config.yaml
kubectl apply -f grafana-deployment.yaml

等待 Pod 重新滚动更新后,配置即生效。


验证:生成 JWT 并测试

生成测试 Token

访问 jwt.io,按以下结构构造 JWT:

Header:

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "<YOUR_KEY_ID>"
}

Payload:

{
  "sub": "test-user",
  "exp": <FUTURE_TIMESTAMP>
}

⚠️ exp 为 Unix 时间戳,需设置为未来时间,否则 Token 会立即过期。kid 必须与 JWKS 中的 kid 一致。

Signature: 使用与 JWKS 中 k 字段相同的密钥进行 HS256 签名。

通过 URL 自动登录

Grafana 启用 url_login = true 后,支持在 URL 中携带 Token 实现免登录跳转:

http://<YOUR_GRAFANA_HOST>:3000/?orgId=1&auth_token=<YOUR_JWT_TOKEN>

浏览器访问该链接,如果 Token 有效,将自动以 JWT 中 sub 字段对应的用户身份登录。


总结

通过以上三步,即可为自建 Grafana 添加 JWT 认证能力。这种方案的典型应用场景包括:

  • 嵌入式仪表盘:在内部系统中通过 URL 传参免登录嵌入 Grafana 面板

  • 统一身份认证:与企业的 SSO / IdP 系统对接,实现单点登录

  • API 集成:通过 HTTP Header 传递 JWT,实现服务间的受控访问

🔒 安全建议:生产环境中建议使用 RS256 等非对称算法代替 HS256,将公钥分发到 Grafana、私钥保存在身份提供商中,避免密钥泄露导致全面失守。同时务必配置 HTTPS,防止 JWT 在传输过程中被截获。

Java 中 SSE (Server-Sent Events) 流式输出与调用完全指南 2026-07-16

评论区