Calling the ShareLink Sharepoint REST API Endpoint, but using the CSOM connection

Pablo Glomby 186 Reputation points
2020-09-02T17:24:48.16+00:00

I have a desktop solution that uses CSOM and I use SharePointOnlineCredentials to get authenticated.
I need to share a file but using the ShareLink endpoint. Although I could share my files using the native CSOM methods, ShareLink provides more options that are needed.

I use SharePoint Online. The way I authenticate using SharePointOnlineCredentials is the standard way (creds = new SharePointOnlineCredentials(szUserName, password);)

This is the function I use:

    private static void ShareFile(string szFileName, ClientContext context, string szLoginUrl, SharePointOnlineCredentials creds)
    {
        try
        {
            string szRelativeRemotePath;
            szRelativeRemotePath = (new Uri(szLoginUrl).AbsolutePath) ;
            string szFullRemotePath_File = "https://" + new Uri(szLoginUrl).Host + szRelativeRemotePath + szDocumentLibrary + "/Attachments/"+ szFileName;
            string szFullRemotePath_API = "https://" + new Uri(szLoginUrl).Host + szRelativeRemotePath + "_api/web/GetFileByUrl(@v)/ListItemAllFields/ShareLink?@v=";
            string szRequestURL = szFullRemotePath_API + "%27" + HttpUtility.UrlEncode(szFullRemotePath_File) + "%27";
            HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(szRequestURL);
            string response = "";
            using (var client = new WebClient())
            {
                client.Credentials = creds;
                client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
                client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
                client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0");
                var endpointUri = new Uri(szRequestURL);
                response = client.UploadString(szRequestURL, "{\"request\":{\"createLink\":true,\"settings\":{\"allowAnonymousAccess\":true,\"linkKind\":2,\"expiration\":null,\"restrictShareMembership\":false,\"updatePassword\":false,\"password\":\"\", \"description\":\"My description\", \"role\":8,\"applicationLink\":false,\"limitUseToApplication\":false}}}");
                dynamic dynObj = JsonConvert.DeserializeObject(response);
                if (dynObj == null )
                {
                    return;
                }
                string szURL= dynObj.d.ShareLink.sharingLinkInfo.Url.Value;
                Console.WriteLine("Sharing link: " + szURL);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error sharing files: " + e.ToString());
        }
    }

The problem is that I get the 403 (Forbidden) error. If instead of calling "client.Credentials = creds;", I register an application in the Azure server, and using ADAL I get the access token and I use "client.Headers.Add("Authorization", "Bearer " + szAccessToken);" then the code works just fine.
This means that the code works fine but there is a problem with the authentication mechanism or maybe if I use a connection with the CSOM credentials then I cannot use that endpoint.
If I connect using the same mechanism but instead of calling that endpoint, I call another endpoint like _layouts/15/download.aspx to download a file, then it works fine.

So until now it smells like if the problem is in the permission that the CSOM connection uses.

Thanks

SharePoint
SharePoint
A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.
10,946 questions
SharePoint Server Development
SharePoint Server Development
SharePoint Server: A family of Microsoft on-premises document management and storage systems.Development: The process of researching, productizing, and refining new or existing technologies.
1,624 questions
0 comments No comments
{count} votes

Accepted answer
  1. Baker Kong-MSFT 3,801 Reputation points
    2020-09-03T03:05:34.337+00:00

    Hi @Pablo Glomby ,

    I understand you want to share a file in a document library (szDocumentLibrary), I did following test:

    1. prepare a test file in a library

    22200-image.png

    1. Try below code:
              ClientContext clientContext = new ClientContext(SiteUrl);  
              clientContext.Credentials = new SharePointOnlineCredentials(username, securestring);  
      
              var web = clientContext.Web;  
      
              var dig=clientContext.GetFormDigestDirect();  
      
              clientContext.Load(web);  
              clientContext.ExecuteQuery();  
      
              Console.WriteLine($"{web.Title}--{dig.DigestValue}");  
      
              ShareFile(clientContext, clientContext.Credentials as SharePointOnlineCredentials,dig.DigestValue);  
      
              Console.ReadKey();  
      
          }  
      
          private static void ShareFile(ClientContext context, SharePointOnlineCredentials creds, string digest)  
          {  
              try  
              {               
                  string szRequestURL = @"https://abc.sharepoint.com/sites/sbdev/_api/web/GetFileByUrl(@v)/ListItemAllFields/ShareLink?@v='/sites/sbdev/My test doc lib/license.txt'";  
      
                  string response = "";  
                  using (var client = new WebClient())  
                  {  
                      client.Credentials = creds;  
                      client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");  
                      client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");  
                      client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");  
                      client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0");  
                      client.Headers.Add("X-RequestDigest", digest);  
      
                      var endpointUri = new Uri(szRequestURL);  
      
      
                      response = client.UploadString(szRequestURL, "{\"request\":{\"createLink\":true,\"settings\":{\"allowAnonymousAccess\":true,\"linkKind\":2,\"expiration\":null,\"restrictShareMembership\":false,\"updatePassword\":false,\"password\":\"\", \"description\":\"My description\", \"role\":8,\"applicationLink\":false,\"limitUseToApplication\":false}}}");  
                      dynamic dynObj = JsonConvert.DeserializeObject(response);  
                      if (dynObj == null)  
                      {  
                          return;  
                      }  
                      string szURL = dynObj.d.ShareLink.sharingLinkInfo.Url.Value;  
                      Console.WriteLine("Sharing link: " + szURL);  
                  }  
              }  
              catch (Exception e)  
              {  
                  Console.WriteLine("Error sharing files: " + e.ToString());  
              }  
          }  
      
      }  
      
      }

    Result:

    22150-image.png

    Could you please have a try?

    Best Regards,
    Baker Kong


    If the response is helpful, please click "Accept Answer" and upvote it.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.