0

I followed this article but I modified the sample code a bit to use GetContextAsync instead of GetAzureADAppOnlyAuthenticatedContext, I get the error "The remote server returned an error: (401) Unauthorized." every single time.

AuthenticationManager authManager = new AuthenticationManager(clientId, certPath,certPassword,tenantId);
using (ClientContext cc = await authManager.GetContextAsync(_siteUrl))
{
    cc.Load(cc.Web, p => p.Title);
    await cc.ExecuteQueryAsync();
    Console.WriteLine(cc.Web.Title);
}

The error is thrown at await cc.ExecuteQueryAsync(); I have uploaded the self-signed certificate onto Azure portal cert

and granted the permission granted

My app is a Winforms app using .NET framework 4.7 PnP.Framework 1.11

P/s: What do I enter for the tenantId param? At the moment I'm using the Directory (tenant) ID from the Overview page tenant

Jack Le
  • 353
  • 2
  • 9

1 Answers1

0

I have tried to reproduce the same in my environment.

  • Created self signed certificate

enter image description here

It is then being uploaded to my app registration

enter image description here

Checked the manifest to confirm

enter image description here

"keyCredentials": [
        {
            "customKeyIdentifier": "xxx",
            "endDate": "2023-01-31T00:00:00Z",
            "keyId": "xxx",
            "startDate": "2023-01-23T00:00:00Z",
            "type": "AsymmetricX509Cert",
            "usage": "Verify",
            "value": "xxx",
            "displayName": "my new ssc"
        }

using postman

enter image description here

code given:

using System;
using PnP.Framework;
//using OfficeDevPnP.Core;
//using Microsoft.SharePoint;
//using Microsoft.SharePoint.Client;
using System.Threading.Tasks;
    
namespace spoapprepo
{
    class Program
    {
        static async void Main(string[] args)
        {
            var clientId = "xxx";
            var certPath = "C:\\xxx\\selfsigned.pfx";
            var certPassword = "xxx";
            var tenantId = "xxx";
            var siteUrl= "https://contoso.sharepoint.com";


            AuthenticationManager authManager = new AuthenticationManager(clientId, certPath, certPassword, tenantId);
Try{
            using (var cc = await authManager.GetContextAsync(siteUrl))
            {
                cc.Load(cc.Web, p => p.Title);
                await cc.ExecuteQueryAsync();
                Console.WriteLine(cc.Web.Title);
            }



            Console.WriteLine("Hello World!");
        }
    }
}
}
catch(ex)
{
Ex.message();
}

Try using if-else and try-catch block to catch the exact error.

As getcontext uses current users credentials , but here we are intended to use app only context.

If users login is not having privileges to access the sharepoint or when entered wrong Login details , the 401 unauthorized usually occurs.

enter image description here

If the user profile needs to be read , it needs user.read permission.

enter image description here

But note the limitation Accessing SharePoint using an application context, also known as app-only | Microsoft Learn here.

User Profile CSOM write operations do not work with Azure AD application Only read operations work.

For writing you need to user to login, use SharePoint App-Only principal

Reference : azure active directory - SharePoint PnP AuthenticationManager login with current user - Stack Overflow

kavyaS
  • 8,026
  • 1
  • 7
  • 19
  • Were you able to reproduce the 401 error using the Azure AD app-only method like I did? Your answer wasn't very clear. With regards to the user profile permission, I have already added the User.Read permission. The intended outcome of my app is to read and write on SP document libraries, not user profile. – Jack Le Jan 24 '23 at 02:06