I have registered my App in Azure with API permission as below:
Here is my python code.
import requests
from msal import ConfidentialClientApplication
client_id = "xxxxxxxxxxxxxxxxxxxxx"
client_secret = "yyyyyyyyyyyyyyyyyyyyy"
tenant_id = "tttttttttttttttttttttttttttttttttttttttt"
site_url = "https://{mytenent}.sharepoint.com/sites/mysite"
resource = "https://{mytenent}"
# Authenticate using client ID and secret
authority = f"https://login.microsoftonline.com/{tenant_id}"
app = ConfidentialClientApplication(
client_id=client_id,
authority=authority,
client_credential=client_secret,
)
scope=[resource + "/.default"]
token_response = app.acquire_token_for_client(scopes=scope)
access_token = token_response.get("access_token") #token_response["access_token"]
print(access_token)
endpoint_url = f"{site_url}/_api/web"
headers = {
"Authorization": "Bearer " + access_token,
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
}
print(endpoint_url)
response = requests.get(endpoint_url, headers=headers)
# Check for errors in the SharePoint API response
if response.status_code == 200:
data = response.json()
print("SharePoint Site Title:", data["d"]["Title"])
else:
print("SharePoint API Error:")
print("Status Code:", response.status_code)
print("Response:", response.text)
By the code print(access_token) I can get the token string so I think I do it right on get a token. But I got 401 response when calling SharePoint API.
Status Code: 401 Response: {"error_description":"ID3035: The request was not valid or is malformed."}
What could be the problem? Thanks for your advice.
I registered one Entra ID application and granted API permissions as below:
Initially, I got same error when I ran your python code in my environment like this:
import requests
from msal import ConfidentialClientApplication
client_id = "xxxxxxxxxxxxxxxxxxxxx"
client_secret = "yyyyyyyyyyyyyyyyyyyyy"
tenant_id = "tttttttttttttttttttttttttttttttttttttttt"
site_url = "https://{mytenent}.sharepoint.com/sites/mysite"
resource = "https://{mytenent}"
# Authenticate using client ID and secret
authority = f"https://login.microsoftonline.com/{tenant_id}"
app = ConfidentialClientApplication(
client_id=client_id,
authority=authority,
client_credential=client_secret,
)
scope=[resource + "/.default"]
token_response = app.acquire_token_for_client(scopes=scope)
access_token = token_response.get("access_token") #token_response["access_token"]
print(access_token)
endpoint_url = f"{site_url}/_api/web"
headers = {
"Authorization": "Bearer " + access_token,
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
}
print(endpoint_url)
response = requests.get(endpoint_url, headers=headers)
# Check for errors in the SharePoint API response
if response.status_code == 200:
data = response.json()
print("SharePoint Site Title:", data["d"]["Title"])
else:
print("SharePoint API Error:")
print("Status Code:", response.status_code)
print("Response:", response.text)
Response:
To resolve the error, you can switch to delegated flows like interactive flow, authorization code flow etc.. for generating token as you granted permissions of Delegated type.
In my case, I ran below modified code that uses interactive flow for generating token and got response successfully like this:
import requests
import msal
client_id = "appId"
tenant_id = "tenantId"
site_url = "https://tenant.sharepoint.com/sites/sridemosite"
resource = "https://tenant.sharepoint.com"
# Authenticate using client ID and secret
authority = f"https://login.microsoftonline.com/{tenant_id}"
app = msal.PublicClientApplication(
client_id,
authority=authority,
)
scope=[resource + "/.default"]
token_response = app.acquire_token_interactive(scopes=scope)
access_token = token_response['access_token']
print(access_token)
endpoint_url = f"{site_url}/_api/web"
headers = {
"Authorization": "Bearer " + access_token,
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
}
print()
print(endpoint_url)
response = requests.get(endpoint_url, headers=headers)
# Check for errors in the SharePoint API response
if response.status_code == 200:
data = response.json()
print("SharePoint Site Title:", data["d"]["Title"])
else:
print("SharePoint API Error:")
print("Status Code:", response.status_code)
print("Response:", response.text)
Response:
Make sure to enable public client flow and add redirect URI in Mobile and desktop applications platform while using interactive flow:
Alternatively, you can also generate access token using client certificate by granting permissions of Application type, refer below blog:
Getting an App Only access token for SharePoint REST APIs by Martin Loitzl