read-tech

Django Grafana Single sign-on

August 24, 2023

In this article, we'll use an HTTP reverse proxy to handle the authentication of Grafana users from Django.

NOTE: Moving forward, we'll refer to our Django server as django-server.xyz and our Grafana server as grafana-server.xyz.

Here we want to authenticate grafana-server.xyz from django-server.xyz, which means that grafana-server.xyz should be accessible from django-server.xyz/grafana along with authentication.

This will be our required steps.

  1. Grafana Configuration
  2. Django reverse proxy
  3. Nginx Setup

Grafana Configuration

Let's start by changing Grafana configs to enable Auth-Proxy. The directory of the config file may differ based on the operating system; please refer to official Documention according to your system.

cd /etc/grafana
sudo nano grafana.ini

In the server block of the file change

root_url = django-server.xyz

This can be the Public IP or domain of django-server.xyz service.

Proxy Configuration

Go to the Auth section and change the auth.proxy part to this

[auth.proxy]
enabled = true
header_name = X-WEBAUTH-USER
header_property = username
auto_sign_up = false

Mark auto_sign_up as true if you want users to log in who already don't have an account in grafana-server.xyz.

Django reverse proxy

Install django-revproxy package

pip install django-revproxy

View

from revproxy.views import ProxyView

class GrafanaProxyView(ProxyView):
    upstream = grafana-server.xyz

    def get_proxy_request_headers(self, request):
        headers = super().get_proxy_request_headers(request)
        http_host = request.META.get("HTTP_HOST")

        headers["X-WEBAUTH-USER"] = request.user.username
        headers["HOST"] = http_host
        return headers

Pass the http_host as a header to fix the origin not allowed warning in Grafana.

Urls

from django.urls import path, include, re_path
from farms.views import GrafanaProxyView

re_path(
        r"^grafana/(?P<path>.*)$", GrafanaProxyView.as_view(), name="grafana-dashboards"
    ),

The endpoint /grafana is customizable change it according to your need

Nginx Setup

Change your grafana-server.xyz nginx configuration to this, location /grafana/ is required to make Grafana Service accessible from grafana-server.xyz/grafana.

server {
    server_name grafana-server.xyz;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
	
    location /grafana/ {
        rewrite ^/grafana(/.*)$ $1 break;
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
	    proxy_set_header Host $host;
    }
}

In the rewrite location block /grafana/ should match with the endpoint that you defined to access Grafana from django-server.zyz.

Restart Nginx

sudo systemctl restart nginx

Now login to Django admin and go to django-server.zyz/grafana to access Grafana.

Thanks for reading!