c# - 无法对来自 .NET Core 的 SharePoint REST 或 CSOM 调用进行身份验证
问题描述
我在使用 CSOM 和 .NET Core 控制台应用程序中的 REST 服务访问 SharePoint 时遇到问题。
首先,我创建了一个面向 .NET Framework 4.6.1 的控制台应用程序,安装了 Microsoft.SharePointOnline.CSOM nuget 包,并添加了两个示例方法以使用硬编码的用户凭据连接到 SharePoint。这行得通。
public static void CsomCall()
{
var password = "password";
var securePassword = new SecureString();
foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);
using (ClientContext context = new ClientContext("https://siteurl"))
{
context.Credentials = new SharePointOnlineCredentials("user@domain", securePassword);
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
Console.WriteLine(web.Title);
}
}
private static void RestCall()
{
var password = "password";
var securePassword = new SecureString();
foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);
var credentials = new SharePointOnlineCredentials("user@domain", securePassword);
using (WebClient client = new WebClient())
{
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
client.Credentials = credentials;
client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
var content = client.DownloadString("https://siteurl/_api/web/lists");
Console.WriteLine(content);
}
}
然后我创建了一个 .NET Core 控制台应用程序并复制了上述方法。我了解 .NET Core 尚不支持 SharePoint CSOM,因此我使用了此处建议的解决方法并手动引用了 Microsoft.SharePoint.Client.Portable.dll、Microsoft.SharePoint.Client.Runtime.Portable.dll 和 Microsoft.SharePoint。 Client.Runtime.Windows.dll。
我必须进行一些更改才能编译代码:
.ExecuteQueryAsync()
代替.ExecuteQuery()
var credentials = new SharePointOnlineCredentials("user@domain", password);
请注意,密码是 Microsoft.SharePoint.Client.Runtime.Portable 中的纯字符串。
运行 CsomCall 时访问 web.Title 时失败:
Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException:'属性或字段'标题'尚未初始化。它尚未被请求或请求尚未执行。可能需要明确要求。
运行 RestCall 时,它会在 client.DownloadString 上出现错误并失败:
System.Net.WebException:'远程服务器返回错误:(401)未经授权。'
是否可以设置 SharePointOnlineCredentials 以使用 .NET Core?对堆栈溢出的搜索表明这应该是可能的,但我似乎无法让它工作。
最终,我们希望使用 ASP.NET Core 构建一个 Web API 服务来为内部用户生成文档(从 SharePoint 读取文档模板,生成新文档并保存回 SharePoint)。使用 CSOM 或 REST,目前在 Windows 操作系统上运行。
解决方案
REST 调用是错误的。您必须使用凭据获取令牌。此外,WebClient 大多已被弃用,请改用 HttpClient 类。
看这个例子:
public const string BaseUri = "https://example.sharepoint.com";
private static HttpClient _client;
public static void Initialize()
{
SharePointOnlineCredentials currentCredentials = GetCredentialsHere();
var handler = new HttpClientHandler
{
Credentials = currentCredentials
};
_client = new HttpClient(handler);
// you are missing this line
handler.CookieContainer.SetCookies(BaseUri, currentCredentials.GetAuthenticationCookie(BaseUri));
_client.BaseAddress = BaseUri;
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.MaxResponseContentBufferSize = 2147483647;
}
推荐阅读
- json - 解码具有单个未键控 bool swift 的 json 文件
- php - Laravel - 从请求中更新大量数据的最佳方法?
- r - ggplot2:geom_bin2d 图中的空白列
- ios - 如何将多行保存到 Firebase,具有自己的自动 ID 的单行?
- flutter - 将水平和垂直滚动条附加到同一个小部件
- algorithm - 逻辑编程 - 查找给定单词的同义词
- python - 将文件一分为二,但保留行
- filter - 用于过滤的 ATR 不适用于斐波那契
- python - 有没有办法让这个子情节看起来写得更少?
- ios - Swift - 我在真实设备上调试时未显示“登录 Apple 按钮”