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 )
几个关键点说明
- Base64填充处理:有些情况下
X-MS-CLIENT-PRINCIPAL的Base64字符串会少=,直接解码会报错,所以要补上缺失的填充符。 - 为什么用ID令牌:
X-MS-CLIENT-PRINCIPAL里的userDetails一般是用户名,不一定是邮箱;而ID令牌里包含了更全的用户属性,比如email、upn这些都是我们需要的。 - JWT解码的小技巧:因为Azure已经帮我们验证过令牌的合法性了,所以这里可以跳过签名验证,直接解码Payload拿信息,省掉不少麻烦。
额外的小提示
如果你不想解码ID令牌,也可以在Function App的「身份验证」设置里,找到「附加声明」选项,把email、upn这些字段添加到X-MS-CLIENT-PRINCIPAL头里,这样直接解码这个头就能拿到所有需要的信息了,更省事。
备注:内容来源于stack exchange,提问作者play_something_good
相关产品推荐
相关产品推荐

