Merge branch 'apache-auth' into operation_standardisation

This commit is contained in:
appleb_m
2026-06-11 16:15:54 +02:00
2 changed files with 5 additions and 42 deletions
-34
View File
@@ -3,7 +3,6 @@ import ipaddress
import logging
import os
import pwd
import re
import uuid
from datetime import datetime, timedelta, UTC
from typing import List
@@ -35,10 +34,6 @@ BATON_REQUEST_TIMEOUT_SECONDS = 30
STAFF_GROUP = "unx-MXgroup"
SUPER_USERS = ["e10019", "e11206", "e18147"]
APACHE_ACCESS_LOG = "/var/log/httpd/daq-access.log"
# Common Log Format: IP - username [timestamp] "request" status bytes ...
_LOG_PATTERN = re.compile(r'^\S+ \S+ (\S+) \[.*?\] ".*?" (\d+)')
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
class TokenData(BaseModel):
@@ -55,35 +50,6 @@ def create_access_token(token: TokenData):
return encoded_jwt
def authenticate_from_apache_log() -> str:
"""
Read the Apache access log and return the username from the most recent
200 response. Apache and the DAQ server are co-located on the same machine.
"""
try:
with open(APACHE_ACCESS_LOG, 'r') as f:
lines = f.readlines()
except OSError as e:
raise AuthenticationException(
message=f"Cannot read Apache access log: {e}",
status_code=401,
headers={"WWW-Authenticate": "Bearer"},
code=AuthErrorCode.INVALID_TOKEN,
) from e
for line in reversed(lines):
m = _LOG_PATTERN.match(line)
if m and m.group(2) == '200' and m.group(1) != '-':
return m.group(1)
raise AuthenticationException(
message="No authenticated user found in Apache access log",
status_code=401,
headers={"WWW-Authenticate": "Bearer"},
code=AuthErrorCode.INVALID_TOKEN,
)
def _is_loopback(host: str | None) -> bool:
if host is None:
return False
+5 -8
View File
@@ -260,21 +260,18 @@ async def login(request: Request, form_data: OAuth2PasswordRequestForm = Depends
"""
Authenticate a user and return an access token.
When the request carries an X-Remote-User header (set by the Apache Kerberos
proxy), the username is taken from that header and the proxy origin is verified.
Otherwise the username from the form data is used (local / dev access).
The request must carry an X-Remote-User header set by the Apache Kerberos
proxy. The client obtains a token by authenticating via Kerberos (NEGOTIATE)
against the Apache proxy, which forwards the request with X-Remote-User set.
Args:
request: The incoming HTTP request (used to inspect headers and client IP).
form_data: OAuth2 password request form containing username and password.
form_data: OAuth2 password request form (unused, required by OAuth2 spec).
Returns:
A dictionary containing the access token and token type.
"""
if request.headers.get("X-Remote-User"):
username = auth.authenticate_from_proxy_header(request)
else:
username = auth.authenticate_from_apache_log()
username = auth.authenticate_from_proxy_header(request)
data = await run_in_threadpool(auth.authenticate_user, cfg, username)
return {"access_token": data, "token_type": "bearer"}