skip to Main Content

I have a React + DRF web app that has JWT authentication, in which I use djangorestframework-simplejwt.

I store access and refresh tokens in the localStorage. Is it possible to use these tokens to authenticate in Grafana? If yes, how can I do that? When I navigate to /grafana (with nginx help), I would like to see that my user in my app to be logged in to the Grafana, by creating the user for Grafana if necessary.

2

Answers


  1. Chosen as BEST ANSWER

    Let me explain all of the details for those who seek a solution to the problem of using common JWT for their app and Grafana. You can skip the beginning if you only care about Grafana side only:

    React side:

    • I have a Django REST Framework API and React UI. When a token returned to the user, React UI saves it to the local storage. I implemented an onClick handler for a button to navigate to Grafana like this:
    // read token value from local storage
    const refToken = localStorage.getItem("refresh_token");
    window.location.href = `/grafana/login/?mytoken=${refToken}`;
    

    Django REST Framework side (djangorestframework-simplejwt):

    • The API can generate and validate JWT tokens using RS256 signing algorithm. Because of the RSA, the API needs to generate 2 keys, private and public key. I have generated those with jwcrypto. I set SIGNING_KEY with the contents of the private key .pem and set VERIFYING_KEY with the contents of the public key .pem.
    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 side:

    • To make sure that this is working, you need to create users with same username for the Grafana. Otherwise you will get Invalid JWT response. auto_sign_up setting is not working for the JWT authentication yet.

    • Then I added these configurations for Grafana container. header_name can be any string and but you need to use it in nginx side too:

    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 side:

    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;
    }
    

  2. It is not clear what is "JWT authentication" and how JWT was created. I guess it is from Open ID Connect authentication, so then nothing is stopping you to use Grafana OIDC auth with the same OIDC identuty provider, to have seamless user single sign on experience.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search