从后台服务验证 Sharepoint 站点并上传文件
Posted
技术标签:
【中文标题】从后台服务验证 Sharepoint 站点并上传文件【英文标题】:Authenticating Sharepoint site from background service and uploading file 【发布时间】:2016-01-29 15:48:45 【问题描述】:我正在尝试针对 Sharepoint 进行身份验证,以便我可以将文件上传到特定的 Sharepoint 站点。
我正在尝试使用 X.509 证书来检索访问令牌,但我不断收到 (401): Unauthorized。
这是我尝试使用证书检索访问令牌的方式:
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
的响应标头中找到它:
【问题讨论】:
您是否配置了 IIS 客户端到用户映射? technet.microsoft.com/en-us/library/cc732996(v=ws.10).aspx 您使用的是什么版本的 SharePoint?现场?等等。这将是许多不同的用户还是单个代理用户。 Sharepoint 2013 是基于声明的身份验证,因此我认为您不会对 x0n 的方法感到满意。大多数人建议使用 ADFS。 您是否考虑过使用 SharePoint 客户端对象模型?您有一个 API 可以完成您在此处尝试完成的大部分工作。 request.Credentials = CredentialCache.DefaultCredentials; 【参考方案1】:更好的方法是使用 SharePoint 客户端对象模型(如 cmets 中建议的 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【讨论】:
以上是关于从后台服务验证 Sharepoint 站点并上传文件的主要内容,如果未能解决你的问题,请参考以下文章
Sharepoint 2010 自定义 Web 服务 - HTTP 请求未经客户端身份验证方案“Ntlm”授权
如何在 SharePoint 中将 Web 部件从一个站点放到另一个站点?
Sharepoint 2013 站点 NTLM 身份验证 javascript doPostBack 在 Safari 和 iPad 中不起作用