Skip to content

'401 Client Error: Unauthorized for url: https://tenant.sharepoint.com/sites/site/_api/contextInfo' when uploading a file to SharePoint with cert auth #983

@nicklockhart-fullfibre

Description

@nicklockhart-fullfibre

Hi all,

Not sure if this is an issue with my environment/setup or a bug with the library. I'm currently trying to migrate a script using SAML auth (see #981) to certificate-based app-only auth. I have a cert which was generated as per the Microsoft documentation, which results in a PFX-format private key. I can see that this library needs a PEM-format private key.

I converted the PFX-format key to PEM-format using openssl:

openssl pkcs12 -in myapp.pfx -out myapp.pem -nodes

If I then check the fingerprint of the PEM-format key, it matches the PFK-format key:

openssl x509 -fingerprint -noout -in myapp.pem
SHA1 Fingerprint=8F:42:8E:60[...]

Screenshot of Windows Certmgr showing the same fingerprint

However, if I then try to upload a file to Sharepoint using certificate authentication...

    login_cert = {
        'tenant': 'tenant.onmicrosoft.com',
        'client_id': 'bc4b906b[...]',
        'thumbprint': '8f428e60[...]',
        'cert_path': '/usr/local/apps/move_to_sharepoint/myapp.pem',
    }
    ctx = ClientContext(site_url).with_client_certificate(**login_cert)

    # Specify destination folder
    folder = ctx.web.get_folder_by_server_relative_url("[path]")

    # Upload file
    local_file_path = args.filename
    with open(local_file_path, "rb") as f:
        file = folder.files.upload(f).execute_query()

...the following error is thrown:

Traceback (most recent call last):
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/client_request.py", line 37, in execute_query
    response = self.execute_request_direct(request)
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/client_request.py", line 46, in execute_request_direct
    self.beforeExecute.notify(request)
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/types/event_handler.py", line 41, in notify
    listener(*args, **kwargs)
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/sharepoint/client_context.py", line 278, in _build_modification_query
    self._ensure_form_digest(request)
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/sharepoint/client_context.py", line 216, in _ensure_form_digest
    self._ctx_web_info = self._get_context_web_information()
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/sharepoint/client_context.py", line 228, in _get_context_web_information
    response = client.execute_request_direct(request)
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/client_request.py", line 101, in execute_request_direct
    response.raise_for_status()
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/requests/models.py", line 1024, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://tenant.sharepoint.com/sites/site/_api/contextInfo

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/apps/move_to_sharepoint/move_to_sharepoint.py", line 37, in <module>
    file = folder.files.upload(f).execute_query()
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/client_object.py", line 55, in execute_query
    self.context.execute_query()
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/client_runtime_context.py", line 173, in execute_query
    self.pending_request().execute_query(qry)
  File "/usr/local/apps/move_to_sharepoint/venv/lib/python3.10/site-packages/office365/runtime/client_request.py", line 41, in execute_query
    raise ClientRequestException(*e.args, response=e.response)
office365.runtime.client_request_exception.ClientRequestException: (None, None, '401 Client Error: Unauthorized for url: https://tenant.sharepoint.com/sites/site/_api/contextInfo')

The app has been granted Sites.FullControl.All as per the library's documentation, so I don't think this is a permissions issue. The file upload code should be correct and previously worked OK when using username/password auth (sadly now deprecated).

Is this an issue with my environment (eg PKCS key converted to X509 via OpenSSL), a bug in my code (eg wrong params passed to with_client_certificate) or have I hit a bug in the library?

I'm using the latest version of the library (2.6.2) with Python 3.10.12 on Ubuntu 22.04 LTS, if that affects anything.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions