简体   繁体   中英

Access denied when downloading file from Sharepoint CSOM

I am trying to download a file from a client Sharepoint site. I am using sharepoint CSOM.

My code is as follows:

using Microsoft.SharePoint.Client;

var username = "username";
var password = "pass";

var url = "https://myclient.sharepoint.com/";
var fileurl = "https://myclient.sharepoint.com/teams/folder1/folder%20x/somefile.docx";
using (ClientContext context = new ClientContext(url))
{    
    SecureString passWord = new SecureString();
    foreach (char c in password.ToCharArray()) passWord.AppendChar(c);
    context.Credentials = new SharePointOnlineCredentials(username, passWord);

    Uri filename = new Uri(fileurl);
    string server = filename.AbsoluteUri.Replace(filename.AbsolutePath, "");
    string serverrelative = filename.AbsolutePath;

    Microsoft.SharePoint.Client.File file = context.Web.GetFileByServerRelativeUrl(serverrelative);
    context.Load(file);
    ClientResult<Stream> streamResult = file.OpenBinaryStream();
    context.ExecuteQuery();
    var file2 = streamResult.Value;
}

The problem is that I get access denied, yet when I log in with the same credentials, I can download the file successfully.

  • Is there a separate permission in Sharepoint for downloading file from API instead of UI?
  • Could the space in the folder name be the problem?

UPDATE

Verified this does not have anything to do with spaces in folder or filename.

In case if SharePoint site uses multiple authentication providers using a set of Windows credentials (also relevant for SharePoint Online), the additional header must be included in a request: X-FORMS_BASED_AUTH_ACCEPTED with a value of f

For ClientContext class the header could be included like this:

ctx.ExecutingWebRequest += (sender, e) =>
{
    e.WebRequestExecutor.WebRequest.Headers["X-FORMS_BASED_AUTH_ACCEPTED"] = "f";
};

Example

var file = ctx.Web.GetFileByUrl(fileAbsUrl);
ctx.Load(file);
var streamResult = file.OpenBinaryStream();
ctx.ExecuteQuery();


//save into file
using (var fileStream = System.IO.File.Create(@"C:\path\filename.docx"))
{
   streamResult.Value.Seek(0, SeekOrigin.Begin);
   streamResult.Value.CopyTo(fileStream);
}

Note: instead of converting to relative url, GetFileByUrl method is used which accepts absolute url

Problem was that I was not connecting to the right url ( new ClientContext(url) )

I was connecting to: https://myclient.sharepoint.com/

I should have been connecting to: https://myclient.sharepoint.com/teams/folder1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM