2015-10-29 8 views
23

Sto tentando di eseguire l'autenticazione con Sharepoint in modo che sia possibile caricare i file su un sito di condivisione specifico.Autenticazione del sito Sharepoint dal servizio in background e caricamento del file

Sto cercando di utilizzare un certificato X.509 per recuperare il token di accesso, ma continuo a ricevere (401): Non autorizzato.

Ecco il modo in cui cerco di recuperare il token di accesso con il certificato:

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

Ed ecco come provo a caricare un file specifico su un preciso elenco di 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 = ""; 
} 

Alcune delle variabili derivano dai parametri:

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

Non sono sicuro di cosa non funzioni e non sono sicuro di come risolvere il problema. Ogni tipo di aiuto è apprezzato.

NOTA: Per favore non mi dica di utilizzare NetworkCredentials, preferisco utilizzare il certificato o qualcos'altro, ma non NetworkCredentials

EDIT

è riuscito a eseguire il debug del codice e trovare questo nell'intestazione della risposta del WebRequest:

enter image description here

+0

Hai configurato cliente IIS per mappatura degli utenti? https://technet.microsoft.com/en-us/library/cc732996(v=ws.10).aspx – x0n

+0

Quale versione di SharePoint stai usando? On Premise? ecc. Saranno anche molti utenti diversi o un singolo utente proxy. –

+0

Sharepoint 2013 è un'autenticazione basata sulle attestazioni, quindi non penso che apprezzerai molto l'approccio di x0n. La maggior parte delle persone consiglia di utilizzare ADFS. –

risposta

1

L'approccio migliore sarebbe utilizzare il modello dell'oggetto lato client di SharePoint (come suggerito da hbulens nei commenti). Ecco il codice che carica il file nella libreria in O365 (basta sostituire le stringhe letterali con i propri dati):

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

è possibile eseguirlo in un'applicazione console. Due DLL che è necessario fare riferimento sono:

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
Problemi correlati