grafana第三方集成以及使用jwt(jwks)实现免登录访问

对于第三方集成grafana,需要可以通过链接直接访问管理界面,跳过登录页面。
传统方法是使用代理认证,而最新的jwt方法可以更好地实现这个需求。
不过网络上相关教程文档较少,缺乏详细说明,故此记录。

一 控制台/面板-分享

grafana本身支持面板的内嵌分享,见 https://grafana.com/docs/grafana/latest/dashboards/share-dashboards-panels
注意修改以下配置,这里以环境变量的写法表示:
domain需要填写外部访问的host
port这里也修改成非默认端口,建议直接修改端口号而不是反向代理形式来隐藏默认端口
下面两个是允许内嵌和允许匿名访问,是关键。

1
2
3
4
5
GF_SERVER_DOMAIN="192.168.100.192"
GF_SERVER_HTTP_PORT=33303
GF_SECURITY_ALLOW_EMBEDDING=true
GF_AUTH_ANONYMOUS_ENABLED=true

二 免登录访问

对于第三方集成grafana,需要可以通过链接直接访问管理界面,跳过登录页面。传统方法是使用代理认证,而最新的jwt方法可以更好地实现这个需求。

1 认证代理方式资料

传统的方法是使用认证代理(Auth Proxy),需和nginx、apache等集成,如:

3 生成token

如下,使用D:\tmp\jwks.json文件,生成用户名为user1,角色为Admin,有效期为1小时的token。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package jwk;

import cn.hutool.core.io.FileUtil;
import com.nimbusds.jose.*;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.mint.DefaultJWSMinter;
import com.nimbusds.jwt.JWTClaimsSet;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;

public class JwtTest {

@Test
public void test() throws Exception {
System.out.println(getJwt());
}

public String getJwt() throws Exception {
JWKSet jwkSet = JWKSet.load(FileUtil.file("D:\\tmp\\jwks.json"));
DefaultJWSMinter minter = new DefaultJWSMinter();
minter.setJWKSource(new ImmutableJWKSet(jwkSet));

JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256)
.type(JOSEObjectType.JWT)
.build();
// Create JWT
Instant nowInstant = Instant.now();
JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder()
.subject("user2")
.expirationTime(new Date(nowInstant.plus(1, ChronoUnit.HOURS).toEpochMilli()))
.notBeforeTime(new Date(nowInstant.toEpochMilli()))
.issueTime(new Date(nowInstant.toEpochMilli()))
.build();
Payload payload = jwtClaims.toPayload();
Map<String, Object> payloadMap = payload.toJSONObject();
payloadMap.put("role", "Admin");
JWSObject jwsObject = minter.mint(header, new Payload(payloadMap), null);
return jwsObject.serialize();
}

}

生成的token可以在https://jwt.io/进行验证,如下

4 使用token进行访问

  1. url-token访问
    http://grafana:33303/datasources?auth_token=YOUR_TOKEN
  2. header访问
    headers携带GF-JWT的token,内容为:Bearer YOUR_TOKEN,注意中间有空格

grafana第三方集成以及使用jwt(jwks)实现免登录访问
https://linshenkx.github.io/grafana-integration-jwt-jwks/
作者
林泽浩
发布于
2022年11月5日
许可协议