如何仅在Django中为仅一个端点(/指标)编写自定义身份验证后端?
我在Django中有一个自定义中间件,可以强制所有请求进行登录身份验证(少数例外,例如api/token
)。
该项目允许用户通过JWT令牌进行身份验证或登录 /admin/login
,所有未经验证的用户都重定向到/admin/login。
用于身份验证。
我们将该项目部署在Kubernetes中,我们希望Prometheus刮擦/Metrics
端点,但我们不希望它将其暴露于未经身份验证的用户。 Prometheus允许使用用户名
和密码
进行身份验证。事实是,当请求发送到/code
时,由于中间件,请求将重定向到/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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我们尝试此方法
调整中间软件以跳过将 /指标端点重定向到 /admin /登录。
将您的loginrequiredmiddleware更新到绕过 /指标身份验证检查PROMITHEUS :(
Middleware.py)
创建一个自定义身份验证后端,用于 /度量标准,该验证可根据用户名&密码,如果有效,将返回已验证的用户。
创建另一个称为backend.py的文件(您可以随心所欲地将其命名)
backends.py)
。
(
lets try this approach
Adjust the middleware to skip redirecting the /metrics endpoint to /admin/login.
Update your LoginRequiredMiddleware to bypass /metrics authentication checks for Promitheus:
(middleware.py)
Create a custom authentication backend for /metrics that checks against a username & password, and returns an authenticated user if valid.
create another file called backend.py(you can name it whatever you like)
(backends.py)
In settings.py, make sure this custom backend is included as an authentication method so it can be recognised:
(settings.py)