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

Microsoft 365 and Office SharePoint For business Windows
Microsoft 365 and Office SharePoint Server Development
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.