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

MSAL Python OBO授权流报错AADSTS90014:凭据中缺少必填字段'iss'

MSAL Python OBO授权流报错AADSTS90014:凭据中缺少必填字段'iss'

我太懂你这种调试到头疼的感觉了——明明JWT里明明有iss字段,客户端应用初始化也没报错,偏偏OBO流就是报“iss缺失”,而且搜遍了帖子都找不到同款问题。结合你的代码和场景,我梳理了几个大概率能解决问题的方向,咱们一个个来排查:

1. 最可能的原因:OBO调用的参数格式完全错误

你的代码里直接把去掉Bearer 的token字符串传给了acquire_token_on_behalf_of,但MSAL Python的这个方法第一个参数要求是包含assertion键的字典,不是直接传token字符串!

虽然JWT本身有iss字段,但因为你传参格式不对,MSAL没办法正确解析这个token,才会抛出“iss缺失”的错误(这个报错确实有点误导人)。

代码修改建议

把你的OBO调用代码改成这样:

@app.route("test", methods=[func.HttpMethod.GET], auth_level=func.AuthLevel.ANONYMOUS)
def leads(req: func.HttpRequest) -> func.HttpResponse:
    authorization: str = req.headers.get("Authorization")  # type: ignore
    if not authorization or not authorization.startswith("Bearer "):
        return func.HttpResponse("Missing or invalid Authorization header", status_code=401)
    
    ua = authorization.removeprefix("Bearer ")
    scopes = ["https://sql.azuresynapse-dogfood.net/user_impersonation"]
    
    # 关键修正:用字典包裹assertion,而不是直接传token字符串
    obo_params = {
        "assertion": ua,
        "requested_token_use": "on_behalf_of"  # 可选,但能明确指定OBO用途
    }
    result = msal_app.acquire_token_on_behalf_of(obo_params, scopes)
    
    if "access_token" not in result:
        body = {"result": result}
        return func.HttpResponse(json.dumps(body), status_code=500)
    else:
        return func.HttpResponse(json.dumps({"result": "success"}), status_code=200, mimetype="application/json")

2. 验证证书与私钥的匹配性(虽然初始化没报错,但不能掉以轻心)

你提到重新生成了证书,虽然ConfidentialClientApplication初始化没报错,但还是要确认:

  • 上传到Entra ID App Registration的server.crt,和函数app环境变量里的私钥是同一对儿生成的
  • 环境变量里的私钥格式是否正确:要确保包含完整的-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----标记,并且换行符没有被吃掉(有些云环境的环境变量会自动去掉换行,导致私钥失效,这种情况初始化时可能不报错,但实际调用OBO时就会出问题)

如果怀疑私钥格式有问题,可以临时在代码里打印私钥内容(测试用,别上线),对比本地的私钥文件,确保完全一致。

3. 检查前端请求的Scopes是否符合OBO流要求

你的前端用的是${CLIENT_ID}/.default作为scope,这个scope是用来获取前端自己的客户端凭证流token的,而OBO流需要的是前端获取的token必须是发给后端API的委托token。

具体来说:

  1. 你的后端App Registration需要暴露一个API(在Entra ID的App Registration里,找到“暴露API”选项卡,设置API ID URI,比如api://backend-client-id)
  2. 前端App Registration需要添加这个后端API的委托权限(在“API权限”里添加,找到你后端的App Registration,勾选对应的委托权限,比如user_impersonation)
  3. 前端请求的scope要改成后端API的ID URI + 权限,比如api://backend-client-id/.default或者api://backend-client-id/user_impersonation

这样前端获取的token才是专门发给后端的,后端才能用这个token成功执行OBO流。

最后总结

先优先修改第一个点——把token用字典包裹传给OBO方法,这是最有可能解决你当前报错的原因。如果改完还是有问题,再依次排查证书匹配性和前端scope的问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:24:52