使用带委派权限的AAD证书应用获取Project Online数据遇401问题求助
问题
我有一个守护程序应用,用于连接Project Online执行OData查询,原流程正常。公司要求切换到证书认证的Azure应用注册(旧认证方式2026年4月2日弃用),已创建应用并配置了SharePoint下的Project.Read、Project.Write、ProjectWebApp.FullControl委派权限。
当前流程:
- 用bash脚本生成受众为
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token的JWT断言 - 通过
client_credentials模式请求Bearer令牌,scope设为https://{tenant_name}.sharepoint.com/.default,成功获取令牌 - 使用该令牌调用Project Online OData接口:
GET https://{tenant_name}.sharepoint.com/sites/{pwa_site}/_api/projectdata/Tasks?$select=TaskId,ProjectId,TaskName&inlinecount=allpages&$top=1
出现401错误:
- 用
https://{tenant_name}.sharepoint.com/.default作为scope时,错误:{"error_description": "ID3035: The request was not valid or is malformed."} - 用
https://graph.microsoft.com/.default作为scope时,错误:{"error_description": "Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown."}
需要解决如何用证书认证的Azure应用获取有效令牌,成功查询Project Online数据。
解决方案
1. 修正权限类型:使用应用权限而非委派权限
守护程序应用采用客户端凭据(client_credentials)认证模式,该模式仅支持应用权限,不支持委派权限。你当前配置的是委派权限,导致令牌无法获得访问Project Online的有效权限:
- 进入Azure AD应用注册→你的应用→API权限→删除现有SharePoint委派权限
- 添加SharePoint的应用权限:选择
Project.Read.All、Project.Write.All或ProjectWebApp.FullControl.All(根据需求选择) - 点击授予管理员同意(必须完成此步骤,否则令牌无权限)
2. 确保Scope与目标资源匹配
调用Project Online的OData接口时,令牌的受众(aud声明)必须是SharePoint资源(https://{tenant_name}.sharepoint.com),因此请求Bearer令牌时的scope必须为:
https://{tenant_name}.sharepoint.com/.default
使用Graph的scope会导致令牌受众为Graph API,调用SharePoint接口时触发受众验证失败(即第二个错误)。
3. 验证令牌的关键声明
用jwt.ms解码你获取的Bearer令牌,确认以下两点:
aud字段值为https://{tenant_name}.sharepoint.comroles字段包含你配置的应用权限(如Project.Read.All)——客户端凭据模式下权限通过roles声明返回,而非委派模式的scp声明
4. 确认JWT断言的正确性
你生成JWT断言的脚本中,受众(AUD)设为https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token是正确的,这是向Azure AD令牌端点提交断言的要求,无需修改。
5. 重试请求
完成上述修正后,重新生成JWT断言、获取Bearer令牌,再调用Project Online的OData接口,即可正常访问数据。
内容的提问来源于stack exchange,提问作者anselmo

