You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Azure AD应用程序编程访问SharePoint文件时遇未授权问题

问题描述

已创建Azure AD应用程序,获取了用户令牌,但访问任意SharePoint站点文件时始终返回**未授权(Unauthorized)**错误。浏览器直接访问文件URL可正常打开,但代码中使用委派用户令牌无法访问。


下载文件代码

using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", userToken);
var respons = await client.GetAsync(url);
if (respons.StatusCode == System.Net.HttpStatusCode.OK)
{
    var downloadStream = await respons.Content.ReadAsStreamAsync();
}
else
{

}

尝试的SharePoint REST API请求方式

string webUrl = "xxx";
string fileUrl = "yyy";
var requestUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}')/$value", webUrl, fileUrl);

使用的授权请求参数

  • 用于Files权限的授权请求:
    https://login.microsoftonline.com/tenantName/oauth2/v2.0/authorize?client_id=theclientID&response_type=code&redirect_uri=http%3A%2F%2Flocalhost&response_mode=query&scope=Files.ReadWrite.All&prompt=consent
    
  • 用于Sites权限的授权请求(尝试访问共享OneDrive/SharePoint文件):
    https://login.microsoftonline.com/tenantName/oauth2/v2.0/authorize?client_id=theclientID&response_type=code&redirect_uri=http%3A%2F%2Flocalhost&response_mode=query&scope=Sites.ReadWrite.All&prompt=consent
    

获取令牌的代码

private async Task<string> GetTokenForUserAsync()
{
    _clientId ="xxx";
    _clientSecret ="yyy";
    _domainName ="zzz";
    string graphUrl = global::Utils.Tools.AzureURL.GetGraphUrl(AzureCloudInstance.AzurePublic);
    string loginUrl = global::Utils.Tools.AzureURL.GetLoginUrl(AzureCloudInstance.AzurePublic);
    loginUrl = string.Format("{0}/{1}", loginUrl, _domainName);
    string redirectUri = "https://myapp.azurewebsites.net";
    IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(_clientId)
        .WithClientSecret(_clientSecret)
        .WithAuthority(loginUrl)
        .WithRedirectUri(redirectUri)
        .Build();

    string[] scopes = new string[] { graphUrl + "/.default" };
    //string[] scopes = new string[] { graphUrl + "/Files.Read.All" };
    Microsoft.Identity.Client.AuthenticationResult result = null;
    result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
    return result.AccessToken;
}

问题原因及解决方法

核心问题:获取的是应用权限令牌,而非委派用户令牌

你当前用AcquireTokenForClient获取的是应用权限令牌,这种令牌基于应用本身的权限,不会模拟用户的身份和权限。而你需要的是委派用户权限令牌,才能以用户身份访问其有权限的SharePoint文件。

具体修正步骤

  1. 切换令牌获取方式
    替换AcquireTokenForClient为适合委派权限的方法,比如授权码流程的AcquireTokenByAuthorizationCode:

    // 假设已通过授权码流程获取到authorizationCode
    var result = await app.AcquireTokenByAuthorizationCode(
        new string[] { "Files.ReadWrite.All", "Sites.ReadWrite.All" },
        authorizationCode)
        .ExecuteAsync();
    

    注意:授权请求中的redirect_uri必须和代码里的redirectUri保持一致(当前授权请求用的是http://localhost,代码里是https://myapp.azurewebsites.net,需统一)。

  2. 统一Scope配置

    • 委派权限的Scope无需加graphUrl + "/"前缀,直接使用权限名称,比如"Files.ReadWrite.All"、"Sites.ReadWrite.All"。
    • 授权请求的Scope必须和令牌获取时的Scope完全一致,避免权限不匹配。
  3. 验证应用权限配置
    在Azure AD应用的「API权限」中,确认已添加对应的委派权限(Files.ReadWrite.All、Sites.ReadWrite.All),且已完成管理员同意(如果是租户级权限)。

  4. REST API请求校验
    调用SharePoint REST API时,确保webUrl是正确的站点URL,fileUrl为服务器相对路径(比如/sites/TestSite/Documents/TestFile.docx);更推荐使用Microsoft Graph API访问文件,兼容性更好。

内容的提问来源于stack exchange,提问作者CloudAnywhere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 09:15:19