diff --git a/backend/app/admin/api/v1/monitor/redis.py b/backend/app/admin/api/v1/monitor/redis.py index 8f93641a..5ae48e72 100644 --- a/backend/app/admin/api/v1/monitor/redis.py +++ b/backend/app/admin/api/v1/monitor/redis.py @@ -1,23 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -from fastapi import APIRouter, Depends +from fastapi import APIRouter from backend.common.response.response_schema import ResponseModel, response_base from backend.common.security.jwt import DependsJwtAuth -from backend.common.security.permission import RequestPermission from backend.utils.redis_info import redis_info router = APIRouter() -@router.get( - '', - summary='redis 监控', - dependencies=[ - Depends(RequestPermission('sys:monitor:redis')), - DependsJwtAuth, - ], -) +@router.get('', summary='redis 监控', dependencies=[DependsJwtAuth]) async def get_redis_info() -> ResponseModel: data = { 'info': await redis_info.get_info(), diff --git a/backend/app/admin/api/v1/monitor/server.py b/backend/app/admin/api/v1/monitor/server.py index becdae51..2c6f66d2 100644 --- a/backend/app/admin/api/v1/monitor/server.py +++ b/backend/app/admin/api/v1/monitor/server.py @@ -1,24 +1,16 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -from fastapi import APIRouter, Depends +from fastapi import APIRouter from starlette.concurrency import run_in_threadpool from backend.common.response.response_schema import ResponseModel, response_base from backend.common.security.jwt import DependsJwtAuth -from backend.common.security.permission import RequestPermission from backend.utils.server_info import server_info router = APIRouter() -@router.get( - '', - summary='server 监控', - dependencies=[ - Depends(RequestPermission('sys:monitor:server')), - DependsJwtAuth, - ], -) +@router.get('', summary='server 监控', dependencies=[DependsJwtAuth]) async def get_server_info() -> ResponseModel: data = { # 扔到线程池,避免阻塞 diff --git a/backend/common/security/rbac.py b/backend/common/security/rbac.py index f2ac3618..e40f4217 100644 --- a/backend/common/security/rbac.py +++ b/backend/common/security/rbac.py @@ -23,6 +23,9 @@ async def rbac_verify(request: Request, _token: str = DependsJwtAuth) -> None: # API 鉴权白名单 if path in settings.TOKEN_REQUEST_PATH_EXCLUDE: return + for pattern in settings.TOKEN_REQUEST_PATH_EXCLUDE_PATTERN: + if pattern.match(path): + return # JWT 授权状态强制校验 if not request.auth.scopes: diff --git a/backend/core/conf.py b/backend/core/conf.py index 10a3fbbe..a86027ef 100644 --- a/backend/core/conf.py +++ b/backend/core/conf.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- from functools import lru_cache -from typing import Any, Literal +from typing import Any, Literal, Pattern from pydantic import model_validator from pydantic_settings import BaseSettings, SettingsConfigDict @@ -70,7 +70,9 @@ class Settings(BaseSettings): TOKEN_REFRESH_REDIS_PREFIX: str = 'fba:refresh_token' TOKEN_REQUEST_PATH_EXCLUDE: list[str] = [ # JWT / RBAC 路由白名单 f'{FASTAPI_API_V1_PATH}/auth/login', - f'{FASTAPI_API_V1_PATH}/auth/logout', + ] + TOKEN_REQUEST_PATH_EXCLUDE_PATTERN: list[Pattern[str]] = [ # JWT / RBAC 路由白名单(正则) + rf'^{FASTAPI_API_V1_PATH}/monitors/(redis|server)$', ] # JWT diff --git a/backend/middleware/jwt_auth_middleware.py b/backend/middleware/jwt_auth_middleware.py index 9dd67a96..2b587998 100644 --- a/backend/middleware/jwt_auth_middleware.py +++ b/backend/middleware/jwt_auth_middleware.py @@ -59,8 +59,12 @@ class JwtAuthMiddleware(AuthenticationBackend): if not token: return None - if request.url.path in settings.TOKEN_REQUEST_PATH_EXCLUDE: + path = request.url.path + if path in settings.TOKEN_REQUEST_PATH_EXCLUDE: return None + for pattern in settings.TOKEN_REQUEST_PATH_EXCLUDE_PATTERN: + if pattern.match(path): + return None scheme, token = get_authorization_scheme_param(token) if scheme.lower() != 'bearer':