如何为应用而非用户授权REST API?移动端调用Graph API遇401错误
解决401未授权:获取应用身份令牌调用Microsoft Graph API
问题原因
你当前使用的是用户上下文的委派权限令牌,但调用bookingBusinesses/appointments API需要使用应用权限令牌(以应用身份而非用户身份发起请求),因此返回401未授权错误。
前置确认
- 你的Azure AD应用已添加Microsoft Graph的应用权限(而非委派权限),比如
BookingsAppointment.Read.All、BookingsAppointment.ReadWrite.All等,且已完成管理员同意(应用权限必须由租户管理员批准生效)。 - 应用注册中已生成客户端密码(Client Secret)或证书,用于应用身份验证。
实现步骤:用客户端凭据流获取应用令牌
推荐使用Microsoft官方的Microsoft.Identity.Client库处理令牌获取,避免手动实现OAuth流程的错误。
- 安装NuGet包:
Install-Package Microsoft.Identity.Client
- 编写令牌获取方法:
using Microsoft.Identity.Client; public async Task<string> GetAppAccessTokenAsync(string tenantId, string clientId, string clientSecret) { var app = ConfidentialClientApplicationBuilder .Create(clientId) .WithClientSecret(clientSecret) .WithAuthority($"https://login.microsoftonline.com/{tenantId}") .Build(); // .default 表示使用应用注册中已配置的所有应用权限 var scopes = new[] { "https://graph.microsoft.com/.default" }; var authResult = await app.AcquireTokenForClient(scopes) .ExecuteAsync() .ConfigureAwait(false); return authResult.AccessToken; }
- 修改API调用代码:
// 替换为你的实际配置 string tenantId = "你的Azure AD租户ID"; string clientId = "应用注册的客户端ID"; string clientSecret = "应用的客户端密码"; string adTenantId = "你的Booking Business租户ID"; // 获取应用令牌 string accessToken = await GetAppAccessTokenAsync(tenantId, clientId, clientSecret).ConfigureAwait(false); // 调用Graph API string url = $@"https://graph.microsoft.com/v1.0/solutions/bookingBusinesses/{adTenantId}/appointments"; using HttpClient client = new(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false); // 处理响应 if (response.IsSuccessStatusCode) { var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); // 解析返回的预约数据 } else { // 输出错误详情排查 var errorDetails = await response.Content.ReadAsStringAsync().ConfigureAwait(false); Console.WriteLine($"请求失败:{response.StatusCode}\n错误详情:{errorDetails}"); }
重要安全提示
移动应用属于公开客户端,无法安全存储客户端密码,直接在移动应用中使用客户端凭据流会导致密码泄露风险。建议架构调整为:
- 搭建自己的后端服务,由后端使用客户端凭据流获取应用令牌并调用Graph API
- 移动应用仅调用你的后端API,由后端中转处理Graph请求
内容的提问来源于stack exchange,提问作者David Shochet
相关产品推荐
相关产品推荐

