Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticating Sharepoint site from background service and uploading file

Tags:

I'm trying to authenticate up against Sharepoint so that it's possible for me to upload files onto a specific Sharepoint site.

I'm trying to use an X.509 certificate to retrieve the access token, but I keep getting (401): Unauthorized.

Here's the way I try to retrieve the access token with the certificate:

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); 

And here's how I try to upload a specific file onto a specific Sharepoint list:

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 = ""; } 

Some of the variables comes from the parameters:

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

I'm not sure what's wrong, and I'm definitely not sure how to fix this.

NOTE: Please don't tell me to use NetworkCredentials, I'd rather use the certificate or something else, but not NetworkCredentials

EDIT

Managed to debug the code and find this in the response header of the WebRequest:

enter image description here

like image 273
Detilium Avatar asked Oct 29 '15 13:10

Detilium


People also ask

How does SharePoint online authentication work?

The root Federation Authentication (rtFA) cookie is used across all of SharePoint. When a user visits a new top-level site or another company's page, the rtFA cookie is used to authenticate them silently without a prompt. When a user signs out of SharePoint, the rtFA cookie is deleted.

Does SharePoint use NTLM authentication?

SharePoint supports the following types of authentication: Windows: All Internet Information Services (IIS) and Windows authentication integration options, including Basic, Digest, Certificates, Windows NT LAN Manager (NTLM), and Kerberos are supported.

Does SharePoint use LDAP?

This article outlines how to configure SharePoint Forms Based Authentication (FBA) to use Lightweight Directory Access Protocol (LDAP), typically used on a SharePoint Extranet.


1 Answers

The better approach would be using the SharePoint Client Side Object Model (as hbulens suggested in comments). Here's the code that uploads the file to the library in O365 (just replace the string literals with your own details):

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(); 

You can run it in console application. Two dll's that you need to reference are:

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
like image 81
Damjan Tomic Avatar answered Oct 24 '22 15:10

Damjan Tomic