【问题标题】:Sharepoint Online Web Api Bearer Error 401Sharepoint Online Web Api 承载错误 401
【发布时间】:2017-11-15 12:01:50
【问题描述】:

我想让 Web Api 在 SPO 上工作。 我做了https://blogs.msmvps.com/windsor/2017/03/12/walkthrough-building-a-custom-web-api-for-use-with-sharepoint-online/ 的示例代码,它运行良好。

现在我想向 SPO 添加一个 get-Request,它也可以在本地运行。 我尝试使用我更喜欢的 clientcontext 和 Webclient 读取文件。 但我总是收到 401 错误“远程服务器返回错误 (401) 未授权”

我不理解 401 错误,因为示例代码可以正常工作。我看不出有什么不同。

        public async Task<IEnumerable<string>> GetUserInfo(string sharePointUrl)
    {
        var results = new List<string>();

        try
        {
            var userToken = this.Request.Headers.Authorization.Parameter;
            var newToken = await GetSharePointAccessToken(sharePointUrl, userToken);

            using (var context = new ClientContext(sharePointUrl))
            {
                context.ExecutingWebRequest +=
                    (s, e) => e.WebRequestExecutor.WebRequest.Headers.Add(
                    "Authorization", "Bearer " + newToken);

                var web = context.Web;
                var user = web.CurrentUser;
                context.Load(user);
                context.ExecuteQuery();

                results.Add(user.Title);
                results.Add(user.LoginName);
                results.Add(user.Email);
            }
        }
        catch (Exception ex)
        {
            results.Add(ex.ToString());
        }

        return results;
    }

这是我的代码 sn-p:

        public async Task<IEnumerable<LessVariables>> GetLess(string url, string id)
    {
       [...]

        var list = new List<LessVariables>();

        try
        {
            var userToken = this.Request.Headers.Authorization.Parameter;
            var newToken = await GetSharePointAccessToken(url, userToken);
            var siteUrl = url;
            var file = siteUrl + "/Style Library/xxx/less/" + id + ".less";
            var files = "/Style Library/xxx/less/" + id + ".less";

            using (var context = new ClientContext(url))
            {
                context.ExecutingWebRequest +=
                    (s, e) => e.WebRequestExecutor.WebRequest.Headers.Add(
                    "Authorization", "Bearer " + newToken);
                context.AuthenticationMode = ClientAuthenticationMode.Default;
                context.ExecuteQuery();
                var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, files);

// After this line I get the 401 error


                using (WebClient client = new WebClient())
                {
                    client.Headers[HttpRequestHeader.Authorization] = "Bearer " + newToken;
                    //client.UseDefaultCredentials = true;
                    string s = client.DownloadString(file);

// After try to DownloadString I got the 401 error.

                    var regex = new Regex(@"(?<name>[@].*:)\s(?<value>.*)(;)");
                    var matches = regex.Matches(s);
                    var parameters = new List<KeyValuePair<string, string>>();

                    foreach (var match in matches.Cast<Match>())
                    {
                        list.Add(new LessVariables
                        {
                            key = match.Groups["name"].Value,
                            value = match.Groups["value"].Value
                        });
                    }
                }
            }
            return list;
        }
        catch (Exception ex)
        { [...]

        }
    }

【问题讨论】:

  • 为了在 SPO 上测试代码,我用于测试目的client.Credentials = new SharePointOnlineCredentials(username, passWord); 代码很好,一切正常,但我不想使用凭据。 API 必须通过令牌进行身份验证。

标签: asp.net sharepoint oauth-2.0 azure-active-directory sharepoint-online


【解决方案1】:

您在读取文件时遇到此行为的原因是请求 http://&lt;site url&gt;//&lt;folder name&gt;/&lt;file name&gt; 会导致重定向,但 WebClient 在执行重定向时会去除授权标头(例如 Bearer 令牌)。 this post 中解释了类似的行为。

由于您以 SharePoint Online 为目标,您可以使用不同的不会导致重定向的方法检索文件内容,例如使用 SharePoint REST API,特别是以下File resource 端点:

Url: http://<site url>/_api/web/getfilebyserverrelativeurl('/<folder name>/<file name>')/$value
Method: Get

示例

using (var client = new WebClient())
{
    client.Headers[HttpRequestHeader.Authorization] = "Bearer " + accessToken;     
    var content = client.DownloadString("https://contoso.sharepoint.com/_api/web/getfilebyserverrelativeurl('/Shared%20Documents/Guide.docx')/$value"); 
    //...     
}

【讨论】:

  • 非常感谢!我不知道我使用完整的 uri 进行了重定向。如果我理解正确,我必须在使用 SPO 时使用 SharePoint REST API?
  • 不强制使用 REST API,其他 API(CSOM、RPC)仍然可用。但考虑到通过 OAuth 持有者令牌进行身份验证的要求和上述限制,我认为 REST 是一种在此处下载文件的方法
  • 好的,谢谢您的回答。最后但并非最不重要的一点 - 我以调用 Web API 的用户的权限执行命令(-> 代表用户/模拟?)?
  • 使用应用程序+用户上下文代表当前登录用户调用Web API,请参阅this article了解更多详情
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
相关资源
最近更新 更多