2015-10-29 27 views
23

Próbuję uwierzytelnić się w stosunku do SharePoint, aby umożliwić mi przesyłanie plików do określonej witryny SharePoint.Uwierzytelnianie witryny Sharepoint z usługi w tle i przesyłanie pliku

Próbuję użyć certyfikatu X.509 do odzyskania tokena dostępu, ale wciąż otrzymuję (401): Nieautoryzowane.

Oto sposób próbuję pobrać token dostępu z certyfikatem:

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

A oto jak próbuję załadować konkretny plik na konkretnej listy programu SharePoint:

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

string requestUriString = string.Format("{0}/_api/web/GetFolderByServerRelativeUrl(@sru)/Files/Add([email protected],overwrite=true)[email protected]='{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 = ""; 
} 

Niektóre zmienne pochodzą z następujących parametrów:

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

Nie jestem pewien, co jest nie tak i zdecydowanie nie jestem pewien, jak to naprawić. Wszelka pomoc jest doceniana.

UWAGA: Proszę nie mów mi używać NetworkCredentials, wolałbym użyć certyfikatu lub coś innego, ale nie NetworkCredentials

EDIT

Zarządzane do debugowania kodu i znaleźć to w nagłówku odpowiedzi na WebRequest:

enter image description here

+0

Czy skonfigurowany klient IIS do mapowania użytkownika? https://technet.microsoft.com/en-us/library/cc732996(v=ws.10).aspx – x0n

+0

Jakiej wersji programu SharePoint używasz? W ofercie? itp. Również będzie to wielu różnych użytkowników lub jednego użytkownika proxy. –

+0

Sharepoint 2013 to uwierzytelnianie oparte na roszczeniach, więc nie sądzę, że będziesz czerpać wiele radości z podejścia x0n. Większość osób sugeruje używanie ADFS. –

Odpowiedz

1

Lepszym rozwiązaniem byłoby użycie modelu obiektu po stronie klienta SharePoint (jak sugerują hbuleny w komentarzach). Oto kod, który przesyła plik do biblioteki w O365 (wystarczy wymienić literały ciągów własnymi szczegóły):

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

można go uruchomić w aplikacji konsoli. Dwie biblioteki DLL, które trzeba odwołać to:

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