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

FastAPI-Azure-Auth配置:SPA未获取自身应用注册角色问题

解决方案:让SPA应用注册控制角色与访问

核心原因

当Swagger SPA请求访问API时,Azure AD默认会在令牌中返回目标API应用注册的角色声明,而非客户端(SPA)自身的角色。要让SPA主导访问控制,需调整令牌请求逻辑与应用注册配置。

具体配置步骤

1. 修改SPA的令牌请求范围

在Swagger的OAuth2配置里,确保请求令牌的scope同时包含SPA自身的应用ID URI(格式为api://<SPA-APP-ID>/.default)和API的权限范围。示例配置如下:

scope: ["api://<API-APP-ID>/.default", "api://<SPA-APP-ID>/.default"]

这样Azure AD返回的令牌会同时携带SPA和API的角色声明,你可在SPA端提取属于自身的Role1角色来控制页面访问。

2. 调整API的权限验证逻辑

在FastAPI中,不要直接依赖API应用注册的角色,转而验证SPA传递的自身角色:

  • 从请求令牌的roles声明中,通过aud字段区分来源(SPA的aud是它自己的应用ID URI),筛选出SPA的角色
  • 基于SPA角色构建访问控制依赖,示例代码:
from fastapi import Depends, HTTPException, status
from fastapi_azure_auth import AzureAuthorizationCodeBearer

azure_scheme = AzureAuthorizationCodeBearer(
    app_client_id="<SPA-APP-ID>",
    tenant_id="<TENANT-ID>",
    scopes={"api://<SPA-APP-ID>/.default": "SPA access"}
)

def get_spa_roles(token: dict = Depends(azure_scheme)):
    spa_roles = [role for role in token.get("roles", []) if token.get("aud") == "api://<SPA-APP-ID>"]
    if not spa_roles:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="无有效SPA角色")
    return spa_roles

@app.get("/protected")
async def protected_route(spa_roles: list = Depends(get_spa_roles)):
    if "Role1" not in spa_roles:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="权限不足")
    return {"message": "访问通过"}

3. 清理冗余角色分配

  • 确认SPA应用注册中已正确添加Role1,且目标用户已被分配该角色
  • 移除用户在API应用注册中的Role7分配,避免令牌中出现混淆的角色声明

4. 可选:改用ID令牌获取SPA角色

若仅需SPA角色,可让Swagger请求ID令牌(ID令牌默认包含客户端应用的角色)。在OAuth2配置中设置response_type: "id_token token",同时获取ID令牌和访问令牌,从ID令牌中提取SPA角色即可。

关键注意点

  • aud字段是区分角色来源的核心:API角色的aud对应API应用ID URI,SPA角色的aud对应SPA应用ID URI
  • 若由SPA完全控制访问,无需在API应用注册中给用户分配任何角色

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:48:14