... Go back to home

Setup JWT untuk Iframe Grafana + Python REST API

  1. Generate RS256 key pair menggunakan openssl

    a. Jalankan command berikut di terminal, pastikan openssl sudah terinstall

    1openssl genpkey -algorithm RSA -out private.key
    2openssl rsa -pubout -in private.key -out public.key
    

    b. Command diatas akan menghasilkan 2 file, private.key dan public.key

    1├── private.key
    2└── public.key
    
  2. Convert isi dari file public.key menjadi format JSON menggunakan https://russelldavies.github.io/jwk-creator/

    a. Copy isi dari file public.key ke dalam field PEM encoded key

    b. isi Key ID dengan grafana

    c. Bagian Public Key Use dan Algorithm biarkan kosong

    d. Klik tombol Convert

  3. Buat file jwks.json

    a. Buat file baru bernama jwks.json dan isi file tersebut dengan JSON berikut

    1{
    2    "keys": []
    3}
    

    b. Copy hasil JWK dari website https://russelldavies.github.io/jwk-creator/ ke dalam array keys di file jwks.json. Contoh seperti berikut:

     1{
     2    "keys": [
     3        {
     4            "kty": "RSA",
     5            "n": "mCE7VaNgkjT0EyiMhyybdOfMaMWbdGyFhmWr-2e4cHY3oVxsLpdT9rcqPUtpGUI9KpRB-V8fcJj8W8YxpTLEFdca-wDP3Vgdyq76-tNYLicMCuvqQD-2PIHDgzPvGBdbj7SZLKs9v8XUfyJ5MhdeSsQVHczgun34h7BfMPhW_qZwd7mXmXB0NHNRVUSYEpBJFmnp6i6CAF5hIRCCxaFZLdzArWg1WXADDJqTC_nVlKMZkpOLTFP5JqtOrWKJGn-uYINyJ0HreXMSehknCZNh1-S7-J8LG--YL2E4JtwkdbbSA-iyuQYRJUT9WezrS-kQSXypntrC-aAH0YOFj9lw8Q",
     6            "e": "AQAB",
     7            "kid": "grafana"
     8        }
     9    ]
    10}
    

    c. Save file jwks.json

  4. Mount jwks.json ke /etc/grafana/jwks.json di container grafana

  5. Atur konfigurasi grafana di file grafana.ini di container grafana

     1[security]
     2allow_embedding = true
     3...
     4
     5[auth.jwt]
     6enabled = true
     7url_login = true
     8header_name = X-JWT-Assertion
     9email_claim = sub
    10username_claim = user
    11jwk_set_file = /etc/grafana/jwks.json
    
  6. Restart container grafana

  7. Untuk mengakses grafana menggunakan JWT, auth_token perlu digenerate terlebih dahulu.

     1import jwt
     2import datetime
     3
     4payload = {
     5    "exp": int((datetime.datetime.now() + datetime.timedelta(hours=50)).timestamp()), # waktu expired token (unix timestamp)
     6    'sub': 'admin@gmail.com', # email user grafana
     7    'user': 'admin', # username user grafana
     8}
     9
    10token = jwt.encode(payload, SECRET_KEY, algorithm='RS256', headers={
    11    'kid': 'grafana' # gunakan key_id (kid) dengan yang ada di jwks.json
    12})
    13
    14token = token.decode('utf-8')
    15
    16print(f'auth_token: {token}')
    
     1from flask_restx import Resource
     2from flask import render_template_string
     3
     4class ApiClass(Resource):
     5    def get(self):
     6        iframe = 'http://localhost:3000/d-solo/a5919b27-0868-44a0-9f4e-28fad226288f/new-dashboard?orgId=1&panelId=1&auth_token=' + token
     7
     8        template = f"""
     9        <iframe
    10            frameborder="0"
    11            noresize="noresize"
    12            style="position: absolute; background: transparent; width: 100%; height: 100%"
    13            src="{ iframe }"
    14            frameborder="0"
    15        ></iframe>
    16        """
    17
    18        return Response(render_template_string(template), mimetype='text/html')