Overview
SharePoint Online is a Software as a Service (SAAS) offering from Microsoft, available as part of Office 365. CSOM (Client Side Object Model) APIs are available for developers to connect to SharePoint Online sites. Using CSOM APIs, we can connect to SharePoint Online remotely and perform desired operations. There are various ways available to connect to SharePoint Online.
In this article, we will explore various options to connect to SharePoint Online. Pros and Cons of each option and mainly how we can connect SharePoint Online site with App Only Authentication.
Connect to SharePoint Online
In a nutshell, the below-managed C# code will help to connect to the SharePoint online site.
public void ConnectToSharePointOnline()
{
string siteCollectionUrl = "https://tenant.sharepoint.com/";
string userName = "[email protected]";
string password = "XXXXXX";
// Namespace: Microsoft.SharePoint.Client
ClientContext ctx = new ClientContext(siteCollectionUrl);
// Namespace: System.Security
SecureString secureString = new SecureString();
password.ToList().ForEach(secureString.AppendChar);
// Namespace: Microsoft.SharePoint.Client
ctx.Credentials = new SharePointOnlineCredentials(userName, secureString);
// Namespace: Microsoft.SharePoint.Client
Site site = ctx.Site;
ctx.Load(site);
ctx.ExecuteQuery();
Console.WriteLine(site.Url.ToString());
}
The above code is fine as long as it is running on a developer’s machine. It is not production-ready, as the credentials are used in a plain text format.
Store credentials in a secure way
Let’s go one step further and store these credentials in a secure way.
The below PowerShell script will help to generate a secure password as an encrypted password.
$key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)
Write-Host "Type the password to encrypt: "
$secureString = Read-Host -AsSecureString
$securePassword = $secureString | ConvertFrom-SecureString -Key $key
We can use this encrypted password in our code or store it in a configuration file. The below PowerShell script will help to decrypt the password.
$key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)
$targetPassword = ConvertTo-SecureString $securePassword -Key $key
The decrypted password can be used to pass credentials to connect to SharePoint online.
In the future, there will be a situation when the password will expire and gets regenerated. It is the moment when our code will stop working.
App Only Authentication
App-Only is a model for setting up app principals. It can be used with SharePoint Online, as will SharePoint OnPremise (SharePoint 2013 / 2016 versions).
Setup app-only principal
Navigate to the SharePoint site (e.g. https://tenant.sharepoint.com)
Open apprehend.aspx page (https://tenant.sharepoint.com/_layouts/15/appregnew.aspx

- Click the “Generate” button against the Client ID row to generate a new client ID
- Click the “Generate” button against the Client secret row to generate a new client secret
- Type any Title, that describes your app's principal
- Type App domain as www.localhost.com
- Specify redirect URI as https://www.localhost.com
- Click Create
- Note down the Client ID and Client Secret for future references
Grant permissions to the newly created principal
The next step is to grant some permission to our created principal. Try to have the permission as granular as it can be. You may create as many numbers of app principals as you need with each app principal having unique permission.
Permission indicates the activity permitted to be performed within a requested scope. The permission can be any of the below:
- Read
- Write
- Manage
- FullControl
Along with permission, we can specify the scope. Below are a few examples of scope.
- http://sharepoint/content/sitecollection
- http://sharepoint/content/sitecollection/web
- http://sharepoint/content/sitecollection/web/list
- http://sharepoint/content/tenant
To give the writer access to a list, we can use the below code
<AppPermissionRequests>
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write"/>
</AppPermissionRequests>
Tenant Scoped Permissions
Tenant-scoped permissions can be only granted from the tenant administration site.
Open SharePoint Online Tenant site with Tenant Administrator account (https:// UNESCO-admin.sharepoint.com/_layouts/15/appinv.aspx)

- In the App ID textbox type your generated Client ID
- Click Lookup button
- In the Permission Request XML textbox type the below XML,
<AppPermissionRequests AllowAppOnlyPolicy="true"> <AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl"/> </AppPermissionRequests>
Click Create button
In the next dialog click Trust It button,

Consume App Only Principal in Code
Use a configuration file to store App ID and App Principals.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<!-- Use AppRegNew.aspx and AppInv.aspx to register client id with secret -->
<add key="ClientId" value="[Your Client ID]" />
<add key="ClientSecret" value="[Your Client Secret]" />
</appSettings>
</configuration>
Office Dev PnP (Office Developer Patterns and Practices) has nuget available to help use app principals in managed C# code.
Use the below-managed C# code to connect to SharePoint
using OfficeDevPnP.Core;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Client;
string siteUrl = "https://tenant.sharepoint.com/sites/demo";
using (var cc = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, "[Your Client ID]", "[Your Client Secret]"))
{
cc.Load(cc.Web, p => p.Title);
cc.ExecuteQuery();
Console.WriteLine(cc.Web.Title);
};
Advantages of using App Principals
- App principals can be consumed from any application (Console, Workflow, etc.)
- We do not need any user credentials to connect to SharePoint.
- Anyone can use app principals to perform activities specified in the scope of app principals.
Summary
App Only Authentication is a secure way to connect to SharePoint without any user dependency. OfficeDevPnP has a NuGet package ready to get started using App Only Authentication. It helps to authenticate with the App Only Policy instead of real user credentials.

Jason RancourtPosted May 12, 2025, 8:59 PM
I currently use CSOM / Username / Password and was hoping to switch to an App ID, butwhen I went to appregnew.aspx I noted the following message: "Starting April 2, 2026, Azure Access Control service (ACS) usage will be retired for SharePoint in Microsoft 365 and users will no longer be able to create or use Azure ACS principals to access SharePoint." Can you tell me can I use the App Principal method with an Entra ID, and can provide information on this? Thanks!
Curtis SpurlockPosted Sep 18, 2024, 7:57 PM
Nanddeep, question about your code - when I run the code I am getting the error System.Net.WebException: 'The remote server returned an error: (403) Forbidden.' The error is happening on the cc.ExecuteQuery() command. Any ideas?
Vinay AyinapurapuPosted May 1, 2024, 2:55 PM
The client credentials auth is soon be deprecated from MSFT. Its time for CBA (Cert Based Auth). thanks for sharing anyways
michlimkbPosted Aug 6, 2021, 3:23 AM
Hi Nanddeep, just wondering whether you have encountered this issue. My solution works when running on other PCs but it only worked once on my pc. I have verified the validity of the clientid and secret and they are not expired. On my PC, it consistently failed (Other than on 1 particular day) when I call GetAppOnlyAuthenticatedContext().
Rostyslav BandurovskyiPosted Jul 30, 2021, 5:28 PM
Hello Nanddeep, i try the code above to connect to SharePoint with ClientId And Client Secret, and i'm getting following error : Microsoft.IdentityModel.SecurityTokenService.RequestFailedException: Token request failed. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized. .....The error is thrown on the new AuthenticationManager().GetAppOnlyAuthenticatedContext codeline. Any advise would really appreciated
Rajat SahaniPosted Feb 13, 2021, 3:12 PM
I would also like highlight that on my tenant two way authorization is enabled.
Rajat SahaniPosted Feb 13, 2021, 3:11 PM
I tried above code. but getting remote server returning unauthorized 401 exception.
PreetiPosted Jan 15, 2021, 9:56 AM
I am doing site association to hubsite with csom . For this I need to get sharepoint context with app plus user permission. how could be achieved this?
ThiagoPosted Dec 18, 2020, 2:31 PM
Hi, i connect with sucess the part 1 Connect to SharePoint Online. but now i need to create a frame in my home page aspx and inside the frame that appoint to sharepoint page and i would like that user will be logged come logged in as previously definedits. without necessity to put login and password again. its possible ?
Sankeerth RamPosted Jun 22, 2020, 8:54 AM
Hi, what are the steps to be used if i need to create an App Only Authentication mechanism for a specific SharePoint and not for all the sharepoints in an organisation?
RAJITHA POTLAPosted Jun 20, 2020, 12:36 PM
Hi, in this lines AppPermissionRequests> <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write"/> </AppPermissionRequests> can you explain how to include list syntax. It's only giving list names from root site
sudhanshu raiPosted Apr 20, 2020, 6:43 AM
Thanks Nanddeep, Dharani has send you the code on u r email-id: [email protected], kindly check and let us know if you find any issue.We are waiting for your reply :).
sudhanshu raiPosted Apr 17, 2020, 12:30 AM
Thanks sir for reply, I have tried with /web also, as I specify in my problem statement, I am getting fields but not items even items available, any possible reason? Ex: List list = cc.Web.Lists.GetByTitle(listName); cc.Load(list); if (list != null) { CamlQuery query = CamlQuery.CreateAllItemsQuery(100); ListItemCollection items = list.GetItems(query); cc.Load(items); cc.ExecuteQuery(); foreach (ListItem listItem in items) { Console.WriteLine(listItem.FieldValues["ID"]); } }
sudhanshu raiPosted Apr 15, 2020, 3:30 AM
Sorry, but its not working in that case also (i.e. load and execute List and then iterate items) but count is always coming as zero, checked with other collection as well, where I a,m member of owner group. I have set scope like : <AppPermissionRequest Scope="https://mysite.sharepoint.com/teams/my-collection/list" Right="FullControl"/>. Do I need to check any rights, MFA or anything, kindly suggest.
sudhanshu raiPosted Apr 13, 2020, 3:31 AM
We are the owner of SharePoint app and already give FullControl to collection. We are able to get the collection names, Field names of particular List but not ListItems. Sample code snipped for reference. using (var clientContext = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, appId, appSecret)) { CamlQuery caml = new CamlQuery(); caml.ViewXml = "<View><Query><OrderBy><FieldRef Name='Created' Ascending='false' /></OrderBy></Query><RowLimit>5</RowLimit></View>"; var requestItems = clientContext.Web.Lists.GetByTitle(listName).GetItems(caml); clientContext.Load(requestItems); clientContext.ExecuteQuery(); foreach (var item in requestItems) //Get 0 count even List contain values { Console.WriteLine(item["Title"]); } }
Ernesto MenesesPosted Jun 22, 2019, 8:23 PM
Does the app only permission have access to Search API ? which permissions should have? THanks
Suhas YerramsettyPosted Jun 11, 2019, 12:21 PM
What is the point of adding ClientId and ClientSecret as keys in App.config and then using them directly in the managed code. Please let me know how to use them as keys in the code as I'm not able to do it.
Sagar RathodPosted Dec 29, 2018, 1:11 AM
Thank you..! Really great content with connecting and Store credentials in a secure wayalong with the other things.
Rushi MehtaPosted Dec 5, 2018, 9:39 PM
Thanks for sharing
Jeevanandham MPosted Dec 5, 2018, 9:13 PM
Thanks for sharing...
Manoj MittalPosted Dec 5, 2018, 10:17 AM
Nanddeep thanks for sharing. Just curious . How you are using PS generated password in CSOM
Daniel KPosted Dec 5, 2018, 10:03 AM
Please give me your contact details
Daniel KPosted Dec 5, 2018, 10:03 AM
Please let me know if you could give SharePoint Online Development Training?