Sharepoint certificate authorization does not work

Open Beginner friendly
#71 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
68/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
python

Research direction

Start in sharepoint.py at the certificate-loading and x5t thumbprint code, then compare its token request with the working test-auth1.py reproduction from the issue. Reproduce the certificate-based login in the oikb container and verify that SharePoint synchronization completes without the 401 response.

Written by the indexing model from the issue text.

Description

I am using the oikb container (latest), and try to connect to sharepoint online:

docker compose exec -it oikb sh
# env | grep SHAREPOINT
SHAREPOINT_CLIENT_ID=***
SHAREPOINT_CERTIFICATE_PATH=/certs/oikb-sharepoint.pem
SHAREPOINT_TENANT_ID=***

But the login does not work:

docker compose logs -f oikb
....
oikb  | {"ts": "2026-07-01T06:12:21Z", "level": "ERROR", "logger": "oikb.daemon", "msg": "Sync failed for sharepoint:***.sharepoint.com/sites/**localPath***: Client error '401 Unauthorized' for url 'https://login.microsoftonline.com/***SHAREPOINT_TENANT_ID***/oauth2/v2.0/token'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401"}

I am not an expert in this area, so I've googled some code to verify the setup:

import os, time, uuid, jwt, requests, base64, hashlib
from cryptography import x509
from cryptography.hazmat.backends import default_backend

tenant = os.environ["SHAREPOINT_TENANT_ID"]
client_id = os.environ["SHAREPOINT_CLIENT_ID"]
pem_path = os.environ["SHAREPOINT_CERTIFICATE_PATH"]

pem = open(pem_path, "rb").read()
private_key = pem.decode()

cert_pem = pem[pem.find(b"-----BEGIN CERTIFICATE-----"):]
cert = x509.load_pem_x509_certificate(cert_pem, default_backend())
der = cert.public_bytes(encoding=__import__("cryptography.hazmat.primitives.serialization").hazmat.primitives.serialization.Encoding.DER)

# SHA-1 thumbprint für x5t, base64url ohne Padding
x5t = base64.urlsafe_b64encode(hashlib.sha1(der).digest()).decode().rstrip("=")

now = int(time.time())
token_url = f"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token"

payload = {
    "aud": token_url,
    "iss": client_id,
    "sub": client_id,
    "jti": str(uuid.uuid4()),
    "nbf": now,
    "exp": now + 600,
}

assertion = jwt.encode(
    payload,
    private_key,
    algorithm="RS256",
    headers={"x5t": x5t}
)

r = requests.post(token_url, data={
    "client_id": client_id,
    "scope": "https://graph.microsoft.com/.default",
    "grant_type": "client_credentials",
    "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
    "client_assertion": assertion,
})

print("STATUS:", r.status_code)
print(r.text)

If I run this code inside the oikb-container, it seems to work:

docker compose run --rm --entrypoint sh oikb -lc 'pip install requests && python /certs/test-auth1.py'
...
STATUS: 200
{"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"***"}

I looks like my setup is fine.

The main difference between the code above and sharepoint.py are these lines:

 # Load certificate to extract thumbprint.
    cert = x509.load_pem_x509_certificate(pem_data)
    thumbprint = cert.fingerprint(cert.signature_hash_algorithm or x509.hashes.SHA256())
    x5t = base64.urlsafe_b64encode(thumbprint).rstrip(b"=").decode("ascii")

Dominant language
Python
Stars
328
Forks
73
Avg merge
4d 18h
Merged PRs (30d)
6

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from open-webui/oikb

All issues in open-webui/oikb

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.