Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failed to use auth code flow with python MSAL

I simply can't get acquire_token_by_auth_code_flow() from the MSAL package to work outside a flask app using the basic example giving in the MSAL documentation.

I think the problem comes from using the wrong authentication response which must be a "dict of the query string received from auth server" according to the documentation. In a flask app, I can simply use request.args which I'm not quite sure how to use outside of flask.

I've already tried using requests.request as well as urlsplit. The device flow is working fine as well as using the MSAL package in Java and connecting via R. So the app seems to be set up correctly.

The basic example code from the MSAL app below produces the error:

state mismatch: XXXXXXXXXXXX vs None

(so auth_response is wrong).
Any thoughts?

import requests
import msal

CLIENT_ID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Application (client) ID of app registration
CLIENT_SECRET = "XX-XXXXXXXX-XXXXXXXX.XX~XXXXX~XXXX" # Placeholder - for use ONLY during testing.
AUTHORITY = "https://login.microsoftonline.com/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX"
REDIRECT_PATH = "/getAToken"  # Used for forming an absolute URL to your redirect URI.
                              # The absolute URL must match the redirect URI you set
                              # in the app's registration in the Azure portal.
ENDPOINT = 'https://graph.microsoft.com/v1.0/me'  
SCOPE = ["https://graph.microsoft.com/.default"]

# Cache
cache = msal.SerializableTokenCache()

# Build msal app
app = msal.ConfidentialClientApplication(
        CLIENT_ID, authority=AUTHORITY,
        client_credential=CLIENT_SECRET, token_cache=cache)

# Initiate auth code flow
session = requests.Session()
session.flow = app.initiate_auth_code_flow(scopes=SCOPE, redirect_uri=REDIRECT_PATH)

# Aquire token
result = app.acquire_token_by_auth_code_flow(auth_code_flow=session.flow, auth_response = dict(parse.parse_qsl(parse.urlsplit(REDIRECT_PATH).query)))

The equivalent code for the last bit from the flask app looks like this with REDIRECT_PATH = "/getAToken":

@app.route(app_config.REDIRECT_PATH)  # Its absolute URL must match your app's redirect_uri set in AAD
def authorized():
    result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
        session.get("flow", {}), request.args)
    return redirect(url_for("index"))
like image 291
Zhuo Han Avatar asked Oct 18 '25 18:10

Zhuo Han


1 Answers

Getting a token requires few requests according to documentation. To make it possible you need to create flow and store it inside session before navigating to microsoft login page.

session["flow"] = _build_auth_code_flow(authority=app_config.AUTHORITY, scopes=app_config.SCOPE)

After navigation back to your application you should use this flow object as you did in your example

result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
        session.get("flow", {}), request.args)

Make sure that you didn't create it twice. In this case error will be similar, but state mismatch: XXXXXXXXXXXX vs XXXXXXXXXXXX. It may happened if you route called twice.

like image 182
Alexander Kukla Avatar answered Oct 21 '25 08:10

Alexander Kukla



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!