让 grafana 使用现有的 JWT 令牌
Make grafana use existing JWT token
我有一个具有 JWT 身份验证的 React + DRF Web 应用程序,我在其中使用 djangorestframework-simplejwt。
我将访问和刷新令牌存储在 localStorage 中。是否可以使用这些令牌在 Grafana 中进行身份验证?如果是,我该怎么做?当我导航到 /grafana(在 nginx 帮助下)时,我希望看到我的应用程序中的用户登录到 Grafana,必要时通过为 Grafana 创建用户。
不清楚什么是“JWT认证”以及JWT是如何创建的。我想这是来自 Open ID Connect 身份验证,所以没有什么能阻止您使用 Grafana OIDC auth 和相同的 OIDC 身份提供商,以获得无缝的用户单点登录体验。
让我为那些寻求解决方案以解决其应用程序和 Grafana 使用通用 JWT 问题的人解释所有细节。如果你只关心 Grafana 方面,你可以跳过开头:
反应方:
- 我有 Django REST Framework API 和 React UI。当令牌返回给用户时,React UI 将其保存到本地存储。我为按钮实现了一个 onClick 处理程序,以便像这样导航到 Grafana:
// read token value from local storage
const refToken = localStorage.getItem("refresh_token");
window.location.href = `/grafana/login/?mytoken=${refToken}`;
Django REST 框架端 (djangorestframework-simplejwt):
- API 可以使用 RS256 签名算法生成和验证 JWT 令牌。由于 RSA,API 需要生成 2 个密钥,私有密钥和 public 密钥。我用
jwcrypto
生成了那些。我用私钥 .pem 的内容设置 SIGNING_KEY
并用 public 密钥 .pem. 的内容设置 VERIFYING_KEY
from jwcrypto import jwk
import uuid
keyid = str(uuid.uuid4())
key = jwk.JWK.generate(kty='RSA', alg='RS256', size=2048, kid=keyid, use='sig')
# export to PEM files
priv_pem = key.export_to_pem(private_key=True, password=None)
pub_pem = key.export_to_pem()
with open("rsa_pub.pem", "wb") as f:
f.write(pub_pem)
with open("rsa.pem", "wb") as f:
f.write(priv_pem)
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=1),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'SIGNING_KEY': open("/path/to/folder/which/has/keys/rsa.pem").read(),
'VERIFYING_KEY': open("/path/to/folder/which/has/keys/rsa_pub.pem").read(),
'ALGORITHM': 'RS256',
'USER_ID_FIELD': 'username',
'USER_ID_CLAIM': 'username',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
}
Grafana 端:
为确保这有效,您需要为 Grafana 创建具有相同用户名的用户。 否则您将得到 Invalid JWT
响应. auto_sign_up
setting is not working for the JWT authentication yet.
然后我为Grafana容器添加了这些配置。 header_name
可以是任何字符串,但你也需要在 nginx 端使用它:
version: "3"
services:
...
...
grafana:
image: grafana/grafana:8.2.2
volumes:
- ...
- "/path/to/folder/which/has/keys:/key_set"
environment:
- "GF_SERVER_ROOT_URL=/grafana/"
- "GF_SERVER_SERVE_FROM_SUB_PATH=true"
- "GF_AUTH_PROXY_ENABLED=true"
- "GF_AUTH_PROXY_ENABLE_LOGIN_TOKEN=true"
- "GF_AUTH_JWT_ENABLED=true"
- "GF_AUTH_JWT_HEADER_NAME=X-JWT-Assertion"
- "GF_AUTH_JWT_USERNAME_CLAIM=username"
- "GF_AUTH_JWT_KEY_FILE=/key_set/rsa_pub.pem"
Nginx 端:
location /grafana/ {
try_files /dev/null @proxy_grafana;
}
location /grafana/login/ {
try_files /dev/null @proxy_grafana_login;
}
location @proxy_grafana {
...
proxy_pass http://grafana:3000;
}
location @proxy_grafana_login {
...
proxy_set_header X-JWT-Assertion "${arg_mytoken}";
proxy_pass http://grafana:3000;
}
我有一个具有 JWT 身份验证的 React + DRF Web 应用程序,我在其中使用 djangorestframework-simplejwt。
我将访问和刷新令牌存储在 localStorage 中。是否可以使用这些令牌在 Grafana 中进行身份验证?如果是,我该怎么做?当我导航到 /grafana(在 nginx 帮助下)时,我希望看到我的应用程序中的用户登录到 Grafana,必要时通过为 Grafana 创建用户。
不清楚什么是“JWT认证”以及JWT是如何创建的。我想这是来自 Open ID Connect 身份验证,所以没有什么能阻止您使用 Grafana OIDC auth 和相同的 OIDC 身份提供商,以获得无缝的用户单点登录体验。
让我为那些寻求解决方案以解决其应用程序和 Grafana 使用通用 JWT 问题的人解释所有细节。如果你只关心 Grafana 方面,你可以跳过开头:
反应方:
- 我有 Django REST Framework API 和 React UI。当令牌返回给用户时,React UI 将其保存到本地存储。我为按钮实现了一个 onClick 处理程序,以便像这样导航到 Grafana:
// read token value from local storage
const refToken = localStorage.getItem("refresh_token");
window.location.href = `/grafana/login/?mytoken=${refToken}`;
Django REST 框架端 (djangorestframework-simplejwt):
- API 可以使用 RS256 签名算法生成和验证 JWT 令牌。由于 RSA,API 需要生成 2 个密钥,私有密钥和 public 密钥。我用
jwcrypto
生成了那些。我用私钥 .pem 的内容设置SIGNING_KEY
并用 public 密钥 .pem. 的内容设置
VERIFYING_KEY
from jwcrypto import jwk
import uuid
keyid = str(uuid.uuid4())
key = jwk.JWK.generate(kty='RSA', alg='RS256', size=2048, kid=keyid, use='sig')
# export to PEM files
priv_pem = key.export_to_pem(private_key=True, password=None)
pub_pem = key.export_to_pem()
with open("rsa_pub.pem", "wb") as f:
f.write(pub_pem)
with open("rsa.pem", "wb") as f:
f.write(priv_pem)
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=1),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'SIGNING_KEY': open("/path/to/folder/which/has/keys/rsa.pem").read(),
'VERIFYING_KEY': open("/path/to/folder/which/has/keys/rsa_pub.pem").read(),
'ALGORITHM': 'RS256',
'USER_ID_FIELD': 'username',
'USER_ID_CLAIM': 'username',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
}
Grafana 端:
为确保这有效,您需要为 Grafana 创建具有相同用户名的用户。 否则您将得到
Invalid JWT
响应.auto_sign_up
setting is not working for the JWT authentication yet.然后我为Grafana容器添加了这些配置。
header_name
可以是任何字符串,但你也需要在 nginx 端使用它:
version: "3"
services:
...
...
grafana:
image: grafana/grafana:8.2.2
volumes:
- ...
- "/path/to/folder/which/has/keys:/key_set"
environment:
- "GF_SERVER_ROOT_URL=/grafana/"
- "GF_SERVER_SERVE_FROM_SUB_PATH=true"
- "GF_AUTH_PROXY_ENABLED=true"
- "GF_AUTH_PROXY_ENABLE_LOGIN_TOKEN=true"
- "GF_AUTH_JWT_ENABLED=true"
- "GF_AUTH_JWT_HEADER_NAME=X-JWT-Assertion"
- "GF_AUTH_JWT_USERNAME_CLAIM=username"
- "GF_AUTH_JWT_KEY_FILE=/key_set/rsa_pub.pem"
Nginx 端:
location /grafana/ {
try_files /dev/null @proxy_grafana;
}
location /grafana/login/ {
try_files /dev/null @proxy_grafana_login;
}
location @proxy_grafana {
...
proxy_pass http://grafana:3000;
}
location @proxy_grafana_login {
...
proxy_set_header X-JWT-Assertion "${arg_mytoken}";
proxy_pass http://grafana:3000;
}