Как написать пользовательский бэкенд аутентификации только для одной конечной точки (/metrics) в Django?

У меня есть пользовательское промежуточное ПО в Django, которое заставляет все запросы проходить через аутентификацию входа (за некоторыми исключениями, такими как api/token).

Этот проект позволяет пользователям аутентифицироваться либо через JWT-токен, либо через логин в /admin/login и все неаутентифицированные пользователи перенаправляются на /admin/login. для аутентификации.

Мы развернули проект в Kubernetes и хотим, чтобы Prometheus скреативил конечную точку /metrics, но не хотим, чтобы она была открыта для неаутентифицированных пользователей. Prometheus позволяет аутентифицироваться с помощью username и password. Дело в том, что когда запрос отправляется на /metrics, из-за промежуточного программного обеспечения запрос перенаправляется на /admin/login.

Поэтому я считаю, что мне нужно написать пользовательский бэкэнд аутентификации, специально разработанный для конечной точки metrics и разместить его перед другими методами аутентификации.

Запрос всегда сначала проходит через промежуточное ПО, поэтому он всегда будет перенаправлен на /admin/login, а затем пройдет через бэкенд аутентификации.

Какой правильный способ сделать это?

  • 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
Вернуться на верх