authenticationoauth-2.0azure-ad-msalmicrosoft-entra-idazure-static-web-app

How to access an API with an Azure identity provider from a Python notebook?


We have an API behind an Entra identity provider. If you call the endpoint in the browser you get redirected to a Microsoft login screen first.

Now we want to be able to use the API from a Python notebook interactively for developers. How can the endpoint be used without the response being the HTML text of a login screen?

We are trying to use MSAL to acquire an authentication token, but the endpoint is still responding with the login screen. What are we doing wrong?

This is our notebook code:

import requests
from msal import PublicClientApplication

# Settings
CLIENT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # <- client id of SWA identity provider app registration
TENANT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
SCOPE = ["api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/user_impersonation"]
API_URL = f"https://example/api/v1/resources/resource"

# Initialize the MSAL confidential client
app = PublicClientApplication(
    CLIENT_ID,
    authority=f"https://login.microsoftonline.com/{TENANT_ID}",
)

flow = app.initiate_device_flow(scopes=SCOPE)
print(flow["message"])  # Provide the user with login instructions
result = app.acquire_token_by_device_flow(flow)

if "access_token" in result:
    token = result["access_token"]
    # Call the API
    headers = {"Authorization": f"Bearer {token}"}
    
    response = requests.get(API_URL, headers=headers)

    if response.status_code == 200:
        print("API Response:", response.text) # <- this responds with login screen HTML, not resource
    else:
        print("Failed to access API:", response.status_code, response.text)
else:
    print("Failed to acquire token:", result.get("error_description"))

Solution

  • To access static web app's API endpoint, you can make use of signed-in user's authentication cookie value and include it with requests as an alternative that can be found here:

    Login to SWA in browser -> Open browser’s developer tools (F12) -> Application tab -> Cookies -> StaticWebAppsAuthCookie:

    enter image description here

    Now, run below sample python code in your runbook by replacing your API URL and cookie's value to get API response:

    import requests
    API_URL = "https://example/api/v1/resources/resource"
    cookies = {
        "StaticWebAppsAuthCookie": "eyJ1c2xxxxxxxxxxxxxxxxxxx"  
    }
    headers = {
        "Accept": "application/json",
    }
    response = requests.get(API_URL, cookies=cookies, headers=headers)
     
    if response.status_code == 200:
        print("API Response:", response.json())  
        
    else:
        print(f"Failed to call API. Status code: {response.status_code}")
        print("Response:", response.text)
    

    Response:

    enter image description here

    Reference:

    Calling Static Web Apps Authenticated API Endpoints by Aaron