- Added `auth.py` for mock login and JWT issuance. - Introduced `chat.py` for handling chat requests with role-based access control. - Enhanced `main.py` to include new routers and middleware for tracing. - Implemented input validation in `input_guard.py` to prevent SQL injection. - Created repositories for managing agent sessions and audit logs. - Added exception handling for authorization errors. - Updated settings to include JWT configuration. - Introduced tests for authentication and input validation.
56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
"""FastAPI 依赖:解析 JWT 并构建 AuthContext。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Annotated
|
|
|
|
from fastapi import Header, Request
|
|
|
|
from app.gateway.jwt_service import decode_token
|
|
from app.gateway.rbac import assert_agent_access
|
|
from app.model.schemas import AgentType, AuthContext
|
|
from app.utils.exceptions import UnauthorizedError
|
|
|
|
|
|
def _parse_bearer(authorization: str | None) -> str:
|
|
if not authorization:
|
|
raise UnauthorizedError("缺少 Authorization 头", error_code="AUTH_401_MISSING")
|
|
scheme, _, token = authorization.partition(" ")
|
|
if scheme.lower() != "bearer" or not token:
|
|
raise UnauthorizedError("Authorization 格式错误", error_code="AUTH_401_FORMAT")
|
|
return token
|
|
|
|
|
|
def get_auth_context(
|
|
request: Request,
|
|
authorization: Annotated[str | None, Header()] = None,
|
|
x_agent_type: Annotated[str | None, Header(alias="X-Agent-Type")] = None,
|
|
) -> AuthContext:
|
|
token = _parse_bearer(authorization)
|
|
payload = decode_token(token)
|
|
trace_id = getattr(request.state, "trace_id", None) or request.headers.get("X-Trace-Id", "unknown")
|
|
|
|
if not x_agent_type:
|
|
raise UnauthorizedError("缺少 X-Agent-Type 头", error_code="AUTH_401_AGENT_TYPE")
|
|
|
|
try:
|
|
agent_type: AgentType = x_agent_type # type: ignore[assignment]
|
|
if agent_type not in ("customer", "advisor", "analyst", "risk"):
|
|
raise ValueError
|
|
except ValueError as exc:
|
|
raise UnauthorizedError("X-Agent-Type 无效", error_code="AUTH_401_AGENT_TYPE") from exc
|
|
|
|
ctx = AuthContext(
|
|
sub=str(payload["sub"]),
|
|
token_type=payload["token_type"],
|
|
roles=list(payload.get("roles") or []),
|
|
permissions=list(payload.get("permissions") or []),
|
|
tenant_id=str(payload.get("tenant_id") or "default"),
|
|
trace_id=trace_id,
|
|
agent_type=agent_type,
|
|
jti=str(payload.get("jti") or ""),
|
|
customer_id=payload.get("customer_id"),
|
|
)
|
|
assert_agent_access(ctx)
|
|
return ctx
|