Connecting to SharePoint with Certificate Authentication using Python

Question:

I am trying to connect to SharePoint Online using Python using Certificate Authentication using https://github.com/vgrem/Office365-REST-Python-Client

If I connect to the root of my SharePoint, it works. But if I try to connect to any specific site, it gets an error. But both work through PowerShell. So I don’t think this is a setup issue.

Example – this is PowerShell using the cert in a .pfx file, connecting to the root (https://mytenant.sharepoint.com)

Connect-PnPOnline -Url https://mytenant.sharepoint.com -Tenant mytenant.onmicrosoft.com -ClientId 5fa2148c-d484-444a-bcf1-db632a0fed71 -CertificatePath 'PowershellPnp.pfx' -CertificatePassword $(ConvertTo-Securestring -string "MyCertPassword" -AsPlainText -Force)

Now I change it to connect to a specific site: https://mytenant.sharepoint.com/sites/MySite

Connect-PnPOnline -Url https://mytenant.sharepoint.com/sites/MySite -Tenant mytenant.onmicrosoft.com -ClientId 5fa2148c-d484-444a-bcf1-db632a0fed71 -CertificatePath 'PowershellPnp.pfx' -CertificatePassword $(ConvertTo-Securestring -string "MyCertPassword" -AsPlainText -Force)

Still works, no errors.

Now I try to do the same thing through Python. I use openssl to convert the .pfx to a .pem file, which is what the Python library wants.

First I try the root https://mytenant.sharepoint.com

site_url = "https://mytenant.sharepoint.com"
cert_settings = {
   'client_id': '5fa2148c-d484-444a-bcf1-db632a0fed71',
   'thumbprint': "D1656C4AAC5CFBB971477230A5FBACCD356829D3",
   'cert_path': 'PowershellPnP.pem'
}
ctx = ClientContext(site_url).with_client_certificate('mytenant.onmicrosoft.com',**cert_settings)

This connects without error.

However, if I change the site to https://mytenant.sharepoint.com/MySite:

    site_url = "https://mytenant.sharepoint.com/sites/MySite"
cert_settings = {
    'client_id': '5fa2148c-d484-444a-bcf1-db632a0fed71',
    'thumbprint': "D1656C4AAC5CFBB971477230A5FBACCD356829D3",
    'cert_path': 'PowershellPnP.pem'
}
ctx = ClientContext(site_url).with_client_certificate('mytenant.onmicrosoft.com',**cert_settings)

I get this error:

ValueError: {‘error’: ‘invalid_resource’, ‘error_description’:
‘AADSTS500011: The resource principal named
https://mytenant.sharepoint.com/sites/MySite was not found in the
tenant named mytenant. This can happen if the application has not been
installed by the administrator of the tenant or consented to by any
user in the tenant. You might have sent your authentication request to
the wrong tenant

I might consider what that error says, but I can connect to that site using the certificate method through PowerShell. So there should be no problem or other requirements to connect to it through Python, no?

It’s not the wrong tenant, and Azure shows everything is consented. And it all works in PowersShell.

Asked By: mannaggia

||

Answers:

Turns out this was a bug in the library.

A workaround until it is fixed is to add a value for the scope parameter:

'scopes': ['https://{tenant}.sharepoint.com/.default']
Answered By: mannaggia