66: Python: MS Graph API Authentication (Without a user)

I’m writing a script to migrate files from one location to another in Sharepoint using MS Graph API.

To use the Graph API, you have to get an authentication token from Azure AD, and there are two ways to do this: 1) Acting on behalf of a user and 2) acting without a user.

Both approaches require you to create an Azure AD App in the Azure portal, but acting on behalf of a user will require an intermediate step of displaying a browser window, so the user can consent to the app acting on their behalf.

For this piece of work, I needed to be able to authenticate without any user involvement. Trying to find good examples of how to do this in Python is devilishly hard, and for a while, I’ve been using option 1, and it’s irked me.

As part of some research into an article I’m writing on Generative AI, I thought I’d see if it could offer a suggestion I could work with.

It did. It gave me the exact answer I was looking for but couldn’t find using GoogleFu!

So here’s the code, in case you’re also looking for it.

import requests

CLIENT_ID = "{your client id}"
TENANT_ID = "{your tenant id}"
CLIENT_SECRET = "{your client secret}" #Don't save this in your code, espically if you're using a public git repo.

url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"
headers = {
    "Content-Type": "application/x-www-form-urlencoded"
}
data = {
    "grant_type": "client_credentials",
    "client_id": CLIENT_ID,
    "client_secret": CLIENT_SECRET,
    "scope": "https://graph.microsoft.com/.default"
}

response = requests.post(url, headers=headers, data=data)

if response.status_code == 200:
    token = response.json()["access_token"]
else:
    print(f"Error getting token: {response.json()}")

The token that’s returned from the /oauth2/v2.0/token will be added as an authorization header to any subsequent call you make to the MS Graph API.

headers = {"AUTHORIZATION": f"Bearer {token}", "Content-type": "application/json"}

What I like about this solution is that it simply uses the request library, making what’s going on more obvious and understandable.

NOTE: I’ve added it to the code, but please don’t keep your client secret in the code. Anyone with access to this can access everything with the scopes allocated to Azure AD App.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s