2

I have a custom middleware in Django to force all the requests to go through a login authentication (with few exceptions like api/token).

This project allows users to authenticate either via a JWT token or a login in /admin/login and all unauthenticated users are redirected to /admin/login. for authentication.

We deployed the project in Kubernetes and we want Prometheus to scrape /metrics endpoint but we don't want it to be exposed to unauthenticated users. Prometheus allows for authentication with username and password. The thing is that when a request is sent to /metrics, because of the middleware, the request is redirected to /admin/login.

So I believe I need to write a custom authentication backend specifically designed for the metrics endpoint and place it before the other authentication methods.

The request always goes through the middleware first so it will always be redirected to /admin/login and then will go through the authentication backend.

What is the right way of doing this?

  • middleware.py
class LoginRequiredMiddleware(MiddlewareMixin):
    def __init__(self, get_response):
        self.get_response = get_response

    def process_request(self, request):
        assert hasattr(request, 'user')

        path = request.path_info.lstrip('/')

        if path == '' or path == '/':
            return self.get_response(request)

        url_is_exempt = any(url.match(path) for url in EXEMPT_URLS)

        if request.user.is_authenticated or url_is_exempt:
            # If the user is authenticated OR the URL is in the exempt list
            # go to the requested page
            return self.get_response(request)

        else:
            # Trying to access any page as a non authenticated user
            return redirect(f"{settings.LOGIN_URL}?next=/{path}")
  • backends.py
class MetricsAuthBackend(BaseBackend):

    def authenticate(self, request, username=None, password=None):
        if '/metrics' in request.path:
            if username == "username":
                #need to fix this to use the hash of the password
                pwd_valid = check_password(password, "password")

                if pwd_valid:
                    user = User.objects.get(username=username)
                    return user

        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
everspader
  • 1,272
  • 14
  • 44

0 Answers0