You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让FastAPI端点兼容Azure AD与API密钥双重认证?

FastAPI多认证方式兼容问题解决(Azure Auth + API Key)

问题背景

我用fastapi-azure-auth实现了Azure用户认证,功能正常,但需要让部分API端点同时支持请求头中的API密钥访问。当前遇到的问题:

  • 仅携带x-api-key的curl请求返回401 Unauthorized
  • 若移除dual_authentication里的Depends(azure_scheme),Swagger完成Azure授权后无法访问端点(不会自动携带Bearer令牌)

需要兼容三个场景:

  • Swagger完成授权后携带令牌请求,返回200 OK
  • curl仅携带X-API-Key请求,返回200 OK
  • curl携带Authorization: Bearer令牌请求,返回200 OK

项目结构:认证配置在dependencies.py,路由定义在api/v1/contracts.py

现有代码

端点代码(api/v1/contracts.py)

@router.get("/", response_model=list[ContractSchema])
def get_contracts(
    filters: ContractFilter = Depends(),
    db: Session = Depends(get_db),
    user: User = Depends(dual_authentication),
) -> list[ContractSchema]:
    return []

认证配置(dependencies.py)

from fastapi_azure_auth.auth import SingleTenantAzureAuthorizationCodeBearer
from fastapi_azure_auth.user import User

azure_scheme = SingleTenantAzureAuthorizationCodeBearer(
    app_client_id=settings.azure_ad.app_client_id,
    tenant_id=settings.azure_ad.tenant_id,
    token_version=1,
    scopes={f"api://{settings.azure_ad.app_client_id}/user_impersonation": "user_impersonation"},
)

api_key_scheme = APIKeyHeader(name="x-api-key", auto_error=False)

protected_dependencies = [Security(azure_scheme, scopes=["user_impersonation"])]

def dual_authentication(
    api_key: Optional[str] = Security(api_key_scheme),
    azure_token: Optional[User] = Depends(azure_scheme)
) -> User:
    """Authenticate via API key or Azure AD."""
    # Check for API key in the header and validate
    if _is_api_key_present_and_valid(api_key):
        return EXTERNAL_API_USER
    
    # Fall back to Azure AD authentication
    if azure_token:
        return azure_token

    # If neither is valid, raise an error
    raise HTTPException(status_code=401, detail="User not authenticated")

问题原因

当前dual_authentication中使用Depends(azure_scheme)时,azure_scheme默认是强制校验的——哪怕参数标记为Optional,当请求只带API Key时,Azure认证逻辑会先触发校验,发现没有Bearer令牌就直接返回401,根本走不到API Key的校验步骤。

而如果移除Depends(azure_scheme),Swagger无法识别该端点需要Azure认证,授权后不会自动携带Bearer令牌,导致请求失败。

解决方案

修改dual_authentication中Azure令牌的依赖方式,用Security替代Depends并添加auto_error=False,让Azure认证变为非强制校验:当没有Bearer令牌时,不会直接抛出401,而是让azure_token为None,继续执行API Key的校验逻辑,同时保留Swagger的认证识别能力。

修改后的dependencies.py代码:

from fastapi_azure_auth.auth import SingleTenantAzureAuthorizationCodeBearer
from fastapi_azure_auth.user import User
from fastapi import Security, HTTPException, APIKeyHeader
from typing import Optional

azure_scheme = SingleTenantAzureAuthorizationCodeBearer(
    app_client_id=settings.azure_ad.app_client_id,
    tenant_id=settings.azure_ad.tenant_id,
    token_version=1,
    scopes={f"api://{settings.azure_ad.app_client_id}/user_impersonation": "user_impersonation"},
)

api_key_scheme = APIKeyHeader(name="x-api-key", auto_error=False)

def dual_authentication(
    api_key: Optional[str] = Security(api_key_scheme),
    azure_token: Optional[User] = Security(azure_scheme, scopes=["user_impersonation"], auto_error=False)
) -> User:
    """Authenticate via API key or Azure AD."""
    # 优先校验API Key
    if api_key and _is_api_key_present_and_valid(api_key):
        return EXTERNAL_API_USER
    
    # 校验Azure令牌
    if azure_token:
        return azure_token

    # 两种认证都失败时返回401
    raise HTTPException(status_code=401, detail="User not authenticated")

关键修改点

  • 将azure_token的依赖从Depends(azure_scheme)改为Security(azure_scheme, scopes=["user_impersonation"], auto_error=False)
  • auto_error=False:让Azure认证在无令牌时不直接返回401,而是将azure_token设为None,继续执行后续逻辑
  • 调整API Key校验条件:明确判断api_key存在再执行校验,避免空值传入校验函数

验证场景

  1. Swagger授权请求:在Swagger中完成Azure OAuth2授权后,请求自动携带Authorization: Bearer令牌,azure_token正常解析,返回200 OK
  2. 仅API Key请求:curl只携带X-API-Key头,校验通过后返回200 OK
    curl -H "X-API-Key: your-valid-api-key" http://localhost:8000/api/v1/contracts/
    
  3. Bearer令牌请求:curl携带Authorization: Bearer令牌,Azure认证通过后返回200 OK
    curl -H "Authorization: Bearer your-azure-token" http://localhost:8000/api/v1/contracts/
    

内容的提问来源于stack exchange,提问作者Emu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:42:13