Embracing the Messiness in Search of Epic Solutions

MSAL: Delegated Access Authentication

Posted

in

,

The Microsoft Authentication Library (MSAL) supports various programming languages and frameworks to simplify the authentication flow against the Microsoft identity platform, which is a prerequisite to invoke APIs such as Microsoft Graph.

In this example, we will write a Python script that performs delegated authentication flow using the user’s credentials. Once authenticated, the script will pull the user’s OneNote data via Microsoft Graph.

Note: While we can also authenticate via app-only access, this is generally scrutinized in larger institutions due to the blast radius. This is because the app can modify other users’ content stored in Microsoft 365 products (emails, calendars, etc).

App Registration and Configuration

Even if you plan to run your program on your local machine, you must register it in the Azure Portal to generate a unique client ID to authenticate.

  • Go to https://portal.azure.com/ and sign in.
  • Go to App Registrations and register your app.
  • Go to the registered app -> Manage (step 1) -> Authentication (step 2). Ensure the following configurations exist:
    • A Mobile and desktop applications platform with the redirect URI set as http://localhost (step 3).
    • The Access tokens (used for implicit flows) option is checked (step 4).
  • Go to the registered app -> Manage (step 1) -> API permissions (step 2).
  • Add the permissions you need (step 3). OneNote’s permissions are added in this example because the script will query OneNote via Microsoft Graph.
  • Before we can call the Microsoft Graph API, these permissions must have green check marks (step 5), accomplished by clicking the Grant admin consent button (step 4). If this button is grayed out, request your institution’s Azure administrators to perform this step on your behalf.

Custom Python Program

Now that the app is registered and configured in the Azure Portal, we can work on the custom script.

Install the msal library.

# requirements.txt

requests
msal

Define the needed variables. The client ID and tenant ID can be retrieved from your registered app in the Azure Portal.

import msal
import requests

CLIENT_ID = '[YOUR_CLIENT_ID]'
TENANT_ID = '[TENANT_ID]'
AUTHORITY = f'https://login.microsoftonline.com/{TENANT_ID}'
SCOPES = ['Notes.Read', 'User.Read']

A function to perform the authentication and to retrieve the access token. MSAL will seamlessly create a web server running on localhost to accept the incoming token data (hence, the need to configure the redirect URI in the Azure Portal).

def get_access_token():
    app = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY)
    result = app.acquire_token_interactive(scopes=SCOPES)
    access_token = result['access_token']

    return access_token

A simple function to query OneNote pages using Microsoft Graph.

def get_onenote_pages(access_token):
    url = 'https://graph.microsoft.com/v1.0/me/onenote/pages'

    headers = {
        'Authorization': f'Bearer {access_token}',
        'Accept': 'application/json'
    }

    response = requests.get(url, headers=headers)
    response.raise_for_status()

    return response.json()

Finally, run the app to test if the app registration and configuration are set up correctly in the Azure Portal.

def run():
    access_token = get_access_token()
    print(access_token)

    onenote_pages = get_onenote_pages(access_token)
    print(onenote_pages)


if __name__ == '__main__':
    run() 

Comments

Leave a Reply