core: cleanup embedded outpost logging, log user for http requests
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
2e06786869
commit
3647633232
|
@ -9,6 +9,7 @@ from rest_framework.exceptions import AuthenticationFailed
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
|
from authentik.core.middleware import KEY_AUTH_VIA, LOCAL
|
||||||
from authentik.core.models import Token, TokenIntents, User
|
from authentik.core.models import Token, TokenIntents, User
|
||||||
from authentik.outposts.models import Outpost
|
from authentik.outposts.models import Outpost
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ def bearer_auth(raw_header: bytes) -> Optional[User]:
|
||||||
if not user:
|
if not user:
|
||||||
raise AuthenticationFailed("Token invalid/expired")
|
raise AuthenticationFailed("Token invalid/expired")
|
||||||
return user
|
return user
|
||||||
|
LOCAL.authentik[KEY_AUTH_VIA] = "api_token"
|
||||||
return tokens.first().user
|
return tokens.first().user
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ def token_secret_key(value: str) -> Optional[User]:
|
||||||
outposts = Outpost.objects.filter(managed=MANAGED_OUTPOST)
|
outposts = Outpost.objects.filter(managed=MANAGED_OUTPOST)
|
||||||
if not outposts:
|
if not outposts:
|
||||||
return None
|
return None
|
||||||
LOGGER.info("Authenticating via secret_key")
|
LOCAL.authentik[KEY_AUTH_VIA] = "secret_key"
|
||||||
outpost = outposts.first()
|
outpost = outposts.first()
|
||||||
return outpost.user
|
return outpost.user
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ SESSION_IMPERSONATE_USER = "authentik_impersonate_user"
|
||||||
SESSION_IMPERSONATE_ORIGINAL_USER = "authentik_impersonate_original_user"
|
SESSION_IMPERSONATE_ORIGINAL_USER = "authentik_impersonate_original_user"
|
||||||
LOCAL = local()
|
LOCAL = local()
|
||||||
RESPONSE_HEADER_ID = "X-authentik-id"
|
RESPONSE_HEADER_ID = "X-authentik-id"
|
||||||
|
KEY_AUTH_VIA = "auth_via"
|
||||||
|
KEY_USER = "user"
|
||||||
|
INTERNAL_HEADER_PREFIX = "X-authentik-internal-"
|
||||||
|
|
||||||
|
|
||||||
class ImpersonateMiddleware:
|
class ImpersonateMiddleware:
|
||||||
|
@ -50,15 +53,17 @@ class RequestIDMiddleware:
|
||||||
}
|
}
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
response[RESPONSE_HEADER_ID] = request.request_id
|
response[RESPONSE_HEADER_ID] = request.request_id
|
||||||
del LOCAL.authentik["request_id"]
|
if auth_via := LOCAL.authentik.get(KEY_AUTH_VIA, None):
|
||||||
del LOCAL.authentik["host"]
|
response[INTERNAL_HEADER_PREFIX + KEY_AUTH_VIA] = auth_via
|
||||||
|
response[INTERNAL_HEADER_PREFIX + KEY_USER] = request.user.username
|
||||||
|
for key in list(LOCAL.authentik.keys()):
|
||||||
|
del LOCAL.authentik[key]
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def structlog_add_request_id(logger: Logger, method_name: str, event_dict):
|
def structlog_add_request_id(logger: Logger, method_name: str, event_dict: dict):
|
||||||
"""If threadlocal has authentik defined, add request_id to log"""
|
"""If threadlocal has authentik defined, add request_id to log"""
|
||||||
if hasattr(LOCAL, "authentik"):
|
if hasattr(LOCAL, "authentik"):
|
||||||
event_dict["request_id"] = LOCAL.authentik.get("request_id", "")
|
event_dict.update(LOCAL.authentik)
|
||||||
event_dict["host"] = LOCAL.authentik.get("host", "")
|
|
||||||
return event_dict
|
return event_dict
|
||||||
|
|
|
@ -3,7 +3,7 @@ from time import time
|
||||||
|
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.core.middleware import RESPONSE_HEADER_ID
|
from authentik.core.middleware import INTERNAL_HEADER_PREFIX, RESPONSE_HEADER_ID
|
||||||
from authentik.root.asgi.types import ASGIApp, Message, Receive, Scope, Send
|
from authentik.root.asgi.types import ASGIApp, Message, Receive, Scope, Send
|
||||||
|
|
||||||
ASGI_IP_HEADERS = (
|
ASGI_IP_HEADERS = (
|
||||||
|
@ -26,6 +26,8 @@ class ASGILogger:
|
||||||
content_length = 0
|
content_length = 0
|
||||||
status_code = 0
|
status_code = 0
|
||||||
request_id = ""
|
request_id = ""
|
||||||
|
# Copy all headers starting with X-authentik-internal
|
||||||
|
copied_headers = {}
|
||||||
location = ""
|
location = ""
|
||||||
start = time()
|
start = time()
|
||||||
|
|
||||||
|
@ -45,9 +47,19 @@ class ASGILogger:
|
||||||
if message["type"] == "http.response.start":
|
if message["type"] == "http.response.start":
|
||||||
response_headers = dict(message["headers"])
|
response_headers = dict(message["headers"])
|
||||||
nonlocal request_id
|
nonlocal request_id
|
||||||
|
nonlocal copied_headers
|
||||||
nonlocal location
|
nonlocal location
|
||||||
request_id = response_headers.get(RESPONSE_HEADER_ID.encode(), b"").decode()
|
request_id = response_headers.get(RESPONSE_HEADER_ID.encode(), b"").decode()
|
||||||
location = response_headers.get(b"Location", b"").decode()
|
location = response_headers.get(b"Location", b"").decode()
|
||||||
|
# Copy all internal headers to log, and remove them from the final response
|
||||||
|
for header in list(response_headers.keys()):
|
||||||
|
if not header.decode().startswith(INTERNAL_HEADER_PREFIX):
|
||||||
|
continue
|
||||||
|
copied_headers[
|
||||||
|
header.decode().replace(INTERNAL_HEADER_PREFIX, "")
|
||||||
|
] = response_headers[header].decode()
|
||||||
|
del response_headers[header]
|
||||||
|
message["headers"] = list(response_headers.items())
|
||||||
|
|
||||||
if message["type"] == "http.response.body" and not message.get("more_body", True):
|
if message["type"] == "http.response.body" and not message.get("more_body", True):
|
||||||
nonlocal start
|
nonlocal start
|
||||||
|
@ -55,6 +67,7 @@ class ASGILogger:
|
||||||
kwargs = {"request_id": request_id}
|
kwargs = {"request_id": request_id}
|
||||||
if location != "":
|
if location != "":
|
||||||
kwargs["location"] = location
|
kwargs["location"] = location
|
||||||
|
kwargs.update(copied_headers)
|
||||||
self.log(scope, runtime, content_length, status_code, **kwargs)
|
self.log(scope, runtime, content_length, status_code, **kwargs)
|
||||||
await send(message)
|
await send(message)
|
||||||
|
|
||||||
|
|
Reference in a new issue