从后台服务认证Sharepoint网站并上传文件

25

我想要对Sharepoint进行身份验证,以便能够将文件上传到特定的Sharepoint网站。

我尝试使用X.509证书来检索访问令牌,但是我一直收到(401):未经授权的消息。

这是我尝试使用证书检索访问令牌的方式:

string authority = SettingsHelper.Authority;
string clientID = SettingsHelper.ClientId;
string serverName = SettingsHelper.SharepointServerName;
//Retreive the certificate path
string certFile = Server.MapPath(SettingsHelper.CertificatePath);
string certPassword = SettingsHelper.CertificatePassword;

AuthenticationResult authenticationResult = null;
AuthenticationContext authenticationContext = new AuthenticationContext(authority);

//Create the certificate file, using the path (certFile), password (certPassword) and the MachineKeySet
X509Certificate2 cert = new X509Certificate2(certFile, certPassword, X509KeyStorageFlags.MachineKeySet);

//Create the ClientAssertionCertificate using the clientID and the actual certificate
ClientAssertionCertificate cac = new ClientAssertionCertificate(clientID, cert);

//Retreive the access token using the serverName and client assertion
authenticationResult = authenticationContext.AcquireToken(serverName, cac);

以下是我如何尝试将特定文件上传到特定的Sharepoint列表:

WebRequest request = null;
HttpWebResponse response = null;
byte[] bytesToUpload = bytes;
var returnValue = "";

string requestUriString = string.Format("{0}/_api/web/GetFolderByServerRelativeUrl(@sru)/Files/Add(url=@fn,overwrite=true)?@sru='{1}'&@fn='{2}'", url, HttpUtility.UrlEncode(serverRelativeUrl), HttpUtility.UrlEncode(fileName));

request = (HttpWebRequest)HttpWebRequest.Create(requestUriString);

request.Method = "POST";
(request as HttpWebRequest).Accept = "*/*";
request.ContentType = "application/json;odata=verbose";
request.Headers.Add("Authorization", String.Format("Bearer {0}", authenticationResult.AccessToken));
request.ContentLength = bytesToUpload.Length;


// Write the local file to the remote system
using (Stream requestStream = request.GetRequestStream())
{
    BinaryWriter writer = new BinaryWriter(requestStream);
    writer.Write(bytesToUpload, 0, bytesToUpload.Length);
    writer.Close();
}
// Get a web response back
response = (HttpWebResponse)request.GetResponse();

using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default))
{
    returnValue = sr.ReadToEnd();
    sr.Close();
}

if (request.RequestUri.ToString().Contains("GetFolderByServerRelativeUrl") == true)
{
    returnValue = "";
}

其中一些变量来自参数:

 UploadEmail(System.IO.File.ReadAllBytes(emlFilePath), "https://(blablabla).sharepoint.com", "sites/(bla)/(bla)/Emails", email.Subject + ".msg");

我不确定出了什么问题,也不知道如何修复。

注意:请不要建议我使用NetworkCredentials,我宁可使用证书或其他方法,但不是NetworkCredentials

编辑

设法调试代码并在WebRequest的响应头中找到了这个:

enter image description here


你已经配置了IIS客户端到用户映射吗?https://technet.microsoft.com/zh-cn/library/cc732996(v=ws.10).aspx - x0n
你正在使用哪个版本的SharePoint?是本地部署还是其他?此外,这将是许多不同用户还是单个代理用户。 - Adam Carr
Sharepoint 2013采用基于声明的身份验证,因此我认为您不太可能从x0n的方法中获得太多乐趣。大多数人建议使用ADFS。 - Adam Carr
2
你考虑过使用SharePoint客户端对象模型吗?你有一个API可以完成你在这里尝试实现的大部分工作。 - hbulens
request.Credentials = CredentialCache.DefaultCredentials; 请求.凭据 = CredentialCache.DefaultCredentials; - David Soler
我注意到你正在访问 https://login.windows.net/common/....我认为该终点已经过时了。如果你将common替换为你的Azure AD租户ID,会发生什么? - Kevin R.
1个回答

1
更好的方法是使用SharePoint客户端对象模型(正如hbulens在评论中建议的那样)。 以下是将文件上传到O365库的代码(只需用自己的详细信息替换字符串文字):
string username = "YOUR_USERNAME";
string password = "YOUR_PASSWORD";
string siteUrl = "https://XXX.sharepoint.com";

ClientContext context = new ClientContext(siteUrl);

SecureString pass = new SecureString();
foreach (char c in password.ToCharArray()) pass.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials(username, pass);

Site site = context.Site;
context.Load(site);
context.ExecuteQuery();

Web web = site.OpenWeb("YOUR_SUBSITE"); 
context.Load(web);
context.ExecuteQuery();

List docLib = web.Lists.GetByTitle("YOUR_LIBRARY");
context.Load(docLib);

FileCreationInformation newFile = new FileCreationInformation();
string filePath = @"YOUR_LOCAL_FILE";

newFile.Content = System.IO.File.ReadAllBytes(filePath);
newFile.Url = System.IO.Path.GetFileName(filePath);

Microsoft.SharePoint.Client.File uploadFile = docLib.RootFolder.Files.Add(newFile);
context.Load(uploadFile);
context.ExecuteQuery();

您可以在控制台应用程序中运行它。您需要引用的两个dll文件是:

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接