Search code examples
sharepointmicrosoft-graph-apisharepoint-onlinemicrosoft-graph-sdkssharepoint-rest-api

How to use SharePoint rest API with Client ID and Client Secret in C# to get site collection?


Is there any way to connect SharePoint Rest API with Client Credentials in C# to get site classifications? I previously used Graph API to get those collections, but I need the same using SharePoint Rest API.

 IConfidentialClientApplication CCA = ConfidentialClientApplicationBuilder
              .Create(c_Id).WithTenantId(t_Id).WithClientSecret(clientSecret).Build();
 ClientCredentialProvider CCP = new ClientCredentialProvider(CCA);
 GraphServiceClient g_Client = new GraphServiceClient(CCP);
 var Sites = await g_Client.Sites.Request().GetAsync();

I used the above code to work with Graph API, How to do the same with SharePoint rest API?


Solution

  • SharePoint Online has blocked Azure AD App Client Secret besides certificates:

    enter image description here

    So it's necessary to create a self signed certificiate and upload for the Azure AD App:

    enter image description here

    For creating the certificate, please follow the official document, create using PowerShell:

    Granting access via Azure AD App-Only

    In C# code firstly, create a class named TokenProvider for example and fill with this code snippet:

    using Microsoft.Identity.Client;
    using System.IO;
    using System.Security.Cryptography.X509Certificates;
    using System.Threading.Tasks;
    
         class TokenProvider
            {
                public static async Task<string> GetAccessTokenAsync(string endpoint)
                {
                    var clientId = "yourclientId";
                    var tenantId = "yourtenantId";
                    
                    var certificate = GetCertificate(Path.Combine("D:\\", "certificatename.pfx"), "certificatepwd");
                    var confidentialClient = ConfidentialClientApplicationBuilder.Create(clientId).WithTenantId(tenantId).WithCertificate(certificate).Build();
                   
                    var token = await confidentialClient.AcquireTokenForClient(new[] { $"{endpoint.TrimEnd('/')}/.default" }).ExecuteAsync();
        
                    return token.AccessToken;
                }
        
                private static X509Certificate2 GetCertificate(string path, string password)
                {
                    return new X509Certificate2(path, password, X509KeyStorageFlags.MachineKeySet);
                }
            }
    

    Then in the Main() function call like this:

           var siteUrl = "https://tenantname.sharepoint.com/";
    
            var token = await TokenProvider.GetAccessTokenAsync(new Uri(siteUrl).GetLeftPart(UriPartial.Authority));
    
            var url = "https://tenantName.sharepoint.com/_api/search/query?querytext='contentclass:sts_site'";
            
            var client = new WebClient();
            client.Headers[HttpRequestHeader.Accept] ="application/json;odata=verbose";
            client.Headers[HttpRequestHeader.ContentType] ="application/json;odata=verbose";
            client.Headers[HttpRequestHeader.Authorization] = "Bearer " + token;
            var json = client.DownloadString(url);