Azure AD令牌验证疑问:Access Token与ID Token选择及验证方法
Azure AD令牌验证与常见问题解答
1. 应该使用access_token还是id_token?
- 向服务器API发起请求时,必须使用access_token,不能用id_token。
- id_token仅用于客户端自身完成用户身份认证(确认用户身份信息),不具备访问受保护API的权限凭证作用。
- access_token是专门的权限令牌,用于向目标API证明请求者拥有对应的访问权限,API会通过验证该令牌来决定是否允许请求。
2. 用户名密码流程下的access_token如何验证?
你遇到的第一个流程中access_token无法验证,核心原因是该令牌的受众(aud字段)并非你的SERVER_ID:
- 当你用
PublicClientApplication结合用户名密码流程,请求scopes=["User.ReadBasic.All"]时,这个access_token的受众是Microsoft Graph API(因为User.ReadBasic.All是Graph的内置权限),而非你的SERVER_ID对应的API,因此验证库会因受众不匹配拒绝验证。 - 正确操作:为SERVER_ID对应的API自定义权限范围(例如
api://SERVER_ID/access_as_user),在获取令牌时请求该自定义范围:import msal app = msal.PublicClientApplication( client_id=SERVER_ID, authority=f"https://login.microsoftonline.com/{TENANT_ID}", ) # 替换为你的API自定义权限范围 result = app.acquire_token_by_username_password( USERNAME, PASSWORD, scopes=["api://SERVER_ID/access_as_user"] ) - 此时获取的access_token受众为SERVER_ID,可正常通过验证库校验。
验证access_token的通用步骤:
- 从Azure AD的元数据端点获取公钥,不需要自行保存私钥
- 验证令牌的签名(用公钥)、受众(
aud必须等于SERVER_ID)、过期时间(exp)、发行者(iss)等核心字段 - 额外校验令牌的权限范围(
scp字段)是否包含API所需的权限
3. 是否需要使用私钥?何时使用?
- 验证access_token不需要使用私钥:Azure AD发行的令牌由Azure的私钥签名,你只需使用Azure公开的公钥验证签名即可。
- 私钥的适用场景:
- 当你的应用作为机密客户端(如后端服务)获取令牌时,可使用私钥替代客户端密码(client_secret)完成身份认证,安全性更高
- 若你自行发行令牌(而非Azure AD提供),才需要用私钥签名令牌,此时验证方需使用你的公钥校验签名
内容的提问来源于stack exchange,提问作者Alberto B
相关产品推荐
相关产品推荐

