Graph Client中OnBehalfOfCredential身份验证失败问题求助
我在.NET Core环境下用Graph Client,通过带idToken的OnBehalfOfCredential做用户身份验证,初始化服务来获取用户日历和个人资料,代码如下:
var scopes = new[] { "User.Read", "Calendars.Read", "Calendars.ReadWrite" }; var clientSecret = "clientSecret"; accessToken = "idToken"; var tenantId = "common"; var clientId = "clientId"; var onBehalfOfCredential = new OnBehalfOfCredential(tenantId, clientId, clientSecret, accessToken); var graphClient = new GraphServiceClient(onBehalfOfCredential, scopes);
这个idToken是Angular项目里用MSAL的loginPopup登录Azure应用后返回的。因为个人账号的accessToken不是JWT格式(以"Ew..."开头),所以我用了idToken,个人账号能正常获取信息,但拿企业或学校账号试的时候,GraphClientService报错:
ERROR: OnBehalfOfCredential authentication failed: AADSTS240002: Input id_token cannot be used as 'urn:ietf:params:oauth:grant-type:jwt-bearer' grant. Trace ID: 10db8442-96cd-47ad-b8d9-3f52a4ee1000 Correlation ID: cd618d21-adc7-4dcb-82bc-9d7b122ca085 Timestamp: 2024-01-18 09:07:51Z
换成企业账号的accessToken后,还是验证失败:
ERROR: "OnBehalfOfCredential authentication failed: AADSTS50013: Assertion failed signature validation. [Reason - Key was found, but use of the key to verify the signature failed., Thumbprint of key used by client: 'E41DE7471B50EE38BC78D0DCDC5CB4E4A7FDED91', Found key 'Start=12/05/2023 17:16:57, End=12/05/2028 17:16:57', Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for app Id '00000000-0000-0000-0000-000000000000']. Trace ID: cf67284a-83ef-429e-bbe0-07cb617e1200 Correlation ID: ed9d2d77-30cb-4bba-9189-16e392a4c528 Timestamp: 2024-01-18 09:20:34Z"
解决AADSTS240002错误
- OBO流程必须用accessToken,不能用idToken:idToken只是确认用户身份的断言,不符合OBO流程的令牌要求。个人账号能成功是特殊场景,企业/教育账号严格遵循OAuth规范,所以必须传正确的accessToken。
- 修改Angular端MSAL配置:调用loginPopup时,指定Graph API的权限范围,确保拿到的accessToken是针对Graph的JWT令牌。代码示例:
const loginRequest = { scopes: ["User.Read", "Calendars.Read", "Calendars.ReadWrite"] }; this.msalService.loginPopup(loginRequest).subscribe(response => { const accessToken = response.accessToken; // 将该accessToken传给.NET Core后端 });
解决AADSTS50013错误
- 核对应用注册密钥:确保.NET Core中使用的
clientSecret和Azure AD应用注册里的客户端密钥完全一致,同时确认密钥在有效期内(错误提示中密钥有效期至2028年,检查是否为当前启用的密钥)。 - 验证accessToken受众:确认Angular端获取的accessToken的
aud字段为Graph API(https://graph.microsoft.com),而非你的应用客户端ID,可通过JWT解析工具查看。 - 配置OBO权限:在Azure AD应用注册中,为后端应用配置代表用户调用Graph的委托权限,若权限需要管理员同意,需完成同意操作。
- 调整租户ID:若主要面向企业/教育账号,将
tenantId从common改为具体租户ID,避免跨租户验证问题。
var scopes = new[] { "User.Read", "Calendars.Read", "Calendars.ReadWrite" }; var clientSecret = "你的有效客户端密钥"; // 此处传入Angular端获取的针对Graph API的accessToken var accessToken = "用户的Graph访问令牌"; // 可选:替换为具体租户ID var tenantId = "你的租户ID"; var clientId = "你的客户端ID"; var onBehalfOfCredential = new OnBehalfOfCredential(tenantId, clientId, clientSecret, accessToken); var graphClient = new GraphServiceClient(onBehalfOfCredential, scopes);
内容的提问来源于stack exchange,提问作者Emre Gundogdu

