Kevin Pope
Kevin Pope

Reputation: 2982

Authentication to Sharepoint Online with CSOM

I feel like I'm missing something here. I'm trying to login to a SPO tenant via a C# Console app, but I'm getting the error:

Cannot contact web site 'https://xxx.sharepoint.com/' or the web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'.

I know the account works, as I'm able to login with the account directly from browsers. In the end, I'd like to use the CSOM to do CRUD operations on SP Lists, Term Stores and Document Libraries, but CSOM is not a hard requirement (and I admittedly don't know if REST APIs can do the whole job).

I've seen that changing the LegacyAuthProtocolsEnabled value to True can help with this, but our security folks won't allow me to enable that feature.

The code is pretty vanilla:

SecureString passWord = getPassword();
using (var context = new ClientContext(URI))
{
    context.Credentials = new SharePointOnlineCredentials(userName, passWord);//new NetworkCredential(userName, passWord);//
    context.Load(context.Web, web => web.Title);
    context.ExecuteQuery(); //Error happens here
    Console.WriteLine("Your site title is: " + context.Web.Title);
}

As you can see, I've also tried passing the NetworkCredentials object, which also doesn't work (I also get a 401 response).

As a further note, I've looked into App-only identities, but I don't believe I can use those due to their restrictions on managing taxonomy (ie. managed metadata within Term Stores) and managing files (though this may be a restriction only on using CSOM, it's not clear to me from this page)

Based on this, can you see what I'm doing wrong here? Or if there's a different/better way to do this, I'm open to that as well!

EDIT: Looks like when LegacyAuthProtocolsEnabled is set to False I explicitly cannot use the SharePointOnlineCredentials class at all, based on this page. Given that, looks like I need a different approach to get this access!

Upvotes: 5

Views: 33893

Answers (3)

Rakesh Dhamejani
Rakesh Dhamejani

Reputation: 109

string siteUrl="your Site Url";
    string username="UserName";
    string password="Password";

    public static ClientContext CreateClientContext(string siteUrl,string username,string password)
    {
        ClientContext context = new ClientContext(siteUrl);
        var securePassword = new SecureString();
        foreach (var chr in password) securePassword.AppendChar(chr);
        context.Credentials = new SharePointOnlineCredentials(username, securePassword);
        return context;
    }

Upvotes: -3

Razvan
Razvan

Reputation: 352

the daemon scenario you are describing can be achieved using an Azure App for authenticating and getting permissions via a JWT token. For a walkthrough see Authenticating to Azure AD non-interactively using a username & password or Windows Integrated Authentication

If you have not worked with azure apps before I recommend you take some time to get acquainted. They are basically trusted principals you create and approve so that your apps use their permissions to perform SharePoint operations.

I am also no longer recommending CSOM for any new developments, especially for SP Online as I believe Microsoft is (more or less openly) retiring this API. Use the PnP library as Gautam also recommended, this is being kept up to date and is a great wrapper for the REST API and also Managed Metadate etc.

Upvotes: 2

Gautam Sheth
Gautam Sheth

Reputation: 2490

This a very common issue which we often face when LegacyAuthProtocolsEnabled is set to False. It also affects us when we have configured Multi-factor Authentication (MFA) in our tenant.

To authenticate to SPO then, we use the GetWebLoginClientContext method of SharePoint PnP Core library which is available as a nuget package.

So, modify your code as below:

AuthenticationManager authManager = new AuthenticationManager();
using (var context = authManager.GetWebLoginClientContext(URI))
{
    context.Load(context.Web, web => web.Title);
    context.ExecuteQuery();
    Console.WriteLine("Your site title is: " + context.Web.Title);
}

Add SharePointPnPCoreOnline Nuget package in your console application. After that, you will be able to login to the SPO env. Basically, this will give you a prompt to enter your details in a browser window.

Upvotes: 10

Related Questions