Connect to SharePoint Online without Basic Authentication from C# Console App

Elmo 41 Reputation points
2022-10-31T12:00:41.643+00:00

Hello,

I have developed a C# Windows Console app. In the past I could connect and write data to SharePoint Online using Basic Authentication very easily. See my (simplified) code here:

using Microsoft.SharePoint.Client;  
using System.Security;  
  
onlineCredentials = new SharePointOnlineCredentials(userName, securePassword);  
  
ClientContext ctx = new ClientContext(myWebsiteUrl)  
ctx.Credentials = onlineCredentials;  
Web web = ctx.Web;  
ctx.Load(web);  
ctx.ExecuteQuery();  

Now, Basic Authentication is disabled in the target Sharepoint Online tenant.

What are the options to connect to SharePoint Online (from my Console application) now? Is the only way to create an Azure app to get ?

Thanks for any help! :)

Regards,
Elmo

SharePoint Development
SharePoint Development
SharePoint: A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.Development: The process of researching, productizing, and refining new or existing technologies.
2,615 questions
0 comments No comments
{count} votes

Accepted answer
  1. Rob Windsor 1,956 Reputation points
    2022-10-31T15:42:35.933+00:00

    Yes, you need to use an Azure app. In addition, if you want to use application permissions with the Client Object Model or the REST API, you need to authenticate using client ID and certificate rather than client ID and client secret. The SharePoint APIs will not work with tokens granted application permissions obtained from Azure AD using client ID and client secret.

    The SharePoint APIs will work with tokens granted delegated permissions obtained from Azure AD using client ID and client secret. In addition, Microsoft Graph will work with tokens granted application or delegated permissions obtained from Azure AD using client ID and client secret.

    Here's some sample code that calls to the Client Object Model using a token granted an application permission. This application uses the Microsoft.Identity.Client and Microsoft.SharePointOnline.CSOM Nuget packages.

    using Microsoft.Identity.Client;  
    using Microsoft.SharePoint.Client;  
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Security.Cryptography.X509Certificates;  
    using System.Text;  
    using System.Threading.Tasks;  
      
    namespace CsomAzureTest  
    {  
        class Program  
        {  
            private static string tenantName = "4qtfk3";  
      
            static void Main(string[] args)  
            {  
                CallClientObjectModel().Wait();  
            }  
      
            private async static Task<string> GetAccessToken()  
            {  
                var clientId = "e198f2a5-952e-4d35-a641-54b5825d3667";  
      
                var certFileName = @"E:\Certs\MicrosoftIdentityPlatformDemos.pfx";  
                var certPassword = "pass@word1";  
                var certificate = new X509Certificate2(certFileName, certPassword,  
                        X509KeyStorageFlags.MachineKeySet);  
      
                var authority = $"https://login.microsoftonline.com/{tenantName}.onmicrosoft.com/";  
                var azureApp = ConfidentialClientApplicationBuilder.Create(clientId)  
                    .WithAuthority(authority)  
                    .WithCertificate(certificate)  
                    .Build();  
      
                var scopes = new string[] { $"https://{tenantName}.sharepoint.com/.default" };  
                var authResult = await azureApp.AcquireTokenForClient(scopes).ExecuteAsync();  
                return authResult.AccessToken;  
            }  
      
            private async static Task CallClientObjectModel()  
            {  
                var token = await GetAccessToken();  
                var siteUrl = $"https://{tenantName}.sharepoint.com/sites/demo";  
      
                using (var context = new ClientContext(siteUrl))  
                {  
                    context.ExecutingWebRequest += (s, e) =>  
                    {  
                        e.WebRequestExecutor.RequestHeaders["Authorization"] =  
                            "Bearer " + token;  
                    };  
      
                    var web = context.Web;  
                    context.Load(web);  
                    context.ExecuteQuery();  
                    Console.WriteLine(web.Title);  
                }  
            }  
        }  
    }  
    

    In the Azure portal, the Sites.Read.All application permission was granted to the app.

    255716-image.png

    In the Azure portal, the CER file for the certificate was uploaded.

    255744-image.png

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Elmo 41 Reputation points
    2022-10-31T16:24:22.967+00:00

    Hi RobWindsor,

    thanks a lot for your great answer. This helps me a lot.

    A few points are still not clear to me:

    Okay, I grant my Azure app specific permissions. And with the combination of the client ID and the certificate my console app can perform specific actions (in your example, the console app can read data from SharePoint sites.)

    Does this mean, that the permissions of the console app are valid for each and every SharePoint site of the tenant?
    What if I want to limit the permissions of the console app to a specific SharePoint site?

    I hope you understand what's my point here: If you cannot limit the permissions of the app to certain SharePoint sites, then everybody who has the client ID and the certificate has read permissions to everything in the tenant, in the worst case to confidential data.

    Regards,
    Emmo