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

Azure Function App(Python):如何获取已认证用户的主体名称、ID及邮箱信息

Azure Function App(Python):如何获取已认证用户的主体名称、ID及邮箱信息

嗨,我完全懂你现在的困扰——已经搞定了Function App的身份验证跳转,登录流程都没问题,但就是拿不到用户的邮箱这些关键信息对吧?别慌,我来一步步帮你解决这个问题。

首先得说,你尝试用的X-MS-CLIENT-PRINCIPAL头确实是对的方向,但它的内容不是直接可读的,而且默认情况下可能没包含邮箱,得先做两步配置+代码处理:

一、先确认身份提供商的配置是否到位

如果你用的是Microsoft Entra ID(原Azure AD),得先检查这两个点:

  • 在对应的应用注册里,给Function App配置的权限中,要勾选User.Read这类能获取用户基本信息(包括邮箱)的权限,并且记得授予管理员同意——不然就算用户登录了,你的应用也没权限拿邮箱。
  • 回到Function App的「身份验证」设置页,确认「令牌存储」里的「将标识信息存储在请求头中」是勾选状态(默认是开的,但保险起见检查下)。

二、在Python代码里正确解码并提取信息

X-MS-CLIENT-PRINCIPAL头的值是Base64编码的JSON,而且有时候会缺Base64的填充符=,得先处理解码;另外,邮箱这类详细信息通常在ID令牌里,所以还要结合X-MS-TOKEN-AAD-ID-TOKEN头来拿。给你贴个实用的代码示例:

import azure.functions as func
import base64
import json
import jwt

def main(req: func.HttpRequest) -> func.HttpResponse:
    # 先拿客户端主体头
    client_principal = req.headers.get('X-MS-CLIENT-PRINCIPAL')
    
    if not client_principal:
        return func.HttpResponse(
            "未检测到已认证用户",
            status_code=401
        )
    
    try:
        # 处理Base64填充问题,解码成JSON对象
        decoded_bytes = base64.b64decode(client_principal + '=' * (-len(client_principal) % 4))
        client_info = json.loads(decoded_bytes.decode('utf-8'))
        
        # 提取基础用户信息
        user_id = f"{client_info.get('identityProvider')}/{client_info.get('userId')}"
        user_name = client_info.get('userDetails')
        
        # 从ID令牌里拿邮箱(这里是关键!)
        id_token = req.headers.get('X-MS-TOKEN-AAD-ID-TOKEN')
        user_email = None
        if id_token:
            # Azure已经验证过令牌有效性,所以直接解码Payload就行,不用验证签名
            token_payload = jwt.decode(id_token, options={"verify_signature": False})
            # 优先取email字段,没有的话用upn(用户主体名称)
            user_email = token_payload.get('email') or token_payload.get('upn')
        
        # 组装返回结果
        result = {
            "用户ID": user_id,
            "用户名称": user_name,
            "用户邮箱": user_email if user_email else "未获取到邮箱信息"
        }
        
        return func.HttpResponse(
            json.dumps(result, ensure_ascii=False),
            mimetype="application/json",
            status_code=200
        )
    
    except Exception as e:
        return func.HttpResponse(
            f"处理用户信息时出错:{str(e)}",
            status_code=500
        )

几个关键点说明

  1. Base64填充处理:有些情况下X-MS-CLIENT-PRINCIPAL的Base64字符串会少=,直接解码会报错,所以要补上缺失的填充符。
  2. 为什么用ID令牌:X-MS-CLIENT-PRINCIPAL里的userDetails一般是用户名,不一定是邮箱;而ID令牌里包含了更全的用户属性,比如email、upn这些都是我们需要的。
  3. JWT解码的小技巧:因为Azure已经帮我们验证过令牌的合法性了,所以这里可以跳过签名验证,直接解码Payload拿信息,省掉不少麻烦。

额外的小提示

如果你不想解码ID令牌,也可以在Function App的「身份验证」设置里,找到「附加声明」选项,把email、upn这些字段添加到X-MS-CLIENT-PRINCIPAL头里,这样直接解码这个头就能拿到所有需要的信息了,更省事。

备注:内容来源于stack exchange,提问作者play_something_good

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 15:59:42