import logging from nicegui import app from fastapi import Request from fastapi.responses import RedirectResponse from starlette.middleware.base import BaseHTTPMiddleware from services.auth.oidc import oidc_config from .access_middleware import get_client_ip from services.log import access_logger as logger class OIDCAuthMiddleware(BaseHTTPMiddleware): """Middleware to handle OIDC authentication""" async def dispatch(self, request: Request, call_next): # Skip authentication for login, callback, and internal routes excluded_paths = {'/login', '/auth/callback'} if (request.url.path.startswith('/_nicegui') or request.url.path in excluded_paths): logger.debug(f"Skipping auth for excluded path: {request.url.path}") return await call_next(request) # Check if user is authenticated if not app.storage.user.get('authenticated', False): client_ip = get_client_ip(request) logger.info(f"Unauthenticated access from {client_ip} to {request.url.path}, redirecting to login") # Store the original URL for redirect after login app.storage.user['redirect_to'] = str(request.url.path) return RedirectResponse('/login') # Validate current token access_token = app.storage.user.get('access_token') if access_token: payload = oidc_config.validate_token(access_token) if not payload: client_ip = get_client_ip(request) user = app.storage.user.get('username', 'unknown') logger.warning(f"Invalid/expired token for user {user} from {client_ip} accessing {request.url.path}, clearing session") # Token is invalid/expired, clear session app.storage.user.clear() return RedirectResponse('/login') else: logger.debug(f"Valid token for user accessing {request.url.path}") return await call_next(request)