AzureAD / microsoft-authentication-library-for-python

Microsoft Authentication Library (MSAL) for Python makes it easy to authenticate to Microsoft Entra ID. General docs are available here https://learn.microsoft.com/entra/msal/python/ Stable APIs are documented here https://msal-python.readthedocs.io. Questions can be asked on www.stackoverflow.com with tag "msal" + "python".

Home Page:https://stackoverflow.com/questions/tagged/azure-ad-msal+python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] PKCE with Non Interactive Authentication

tanios13 opened this issue · comments

MSAL client type

Public

Problem Statement

Hello,

I would like to create a flask webapp where the user authenticate with the PublicClientApplication and not the ConfidentialClientApplication. For this, I read in the documentation that I should use PKCE.

I did the following:

flow = msal_app.initiate_auth_code_flow(
        scopes=["User.Read"],
        redirect_uri=REDIRECT_URI
    )
    
session["flow"] = flow

and then.

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

I saw that the flow dict contains the code verifier which should be enough for the PKCE. However, I get the following error:

invalid_client - AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.

Proposed solution

I would like a way of authenticating without storing the Client_Secret or using Interactive Browser, i.e. using PKCE.

I think you are mixing up different concepts here.

I would like to create a flask webapp where the user authenticates with the PublicClientApplication and not the ConfidentialClientApplication.

No. Based on OAuth2's client type definition, a (flask or not) webapp is typically a confidential client.

Besides, regardless of you use PublicClientApplication.acquire_token_interactive() or ConfidentialClientApplication.initiate_auth_code_flow(), MSAL Python automatically and always enables PKCE for you. So, "whether you should use PKCE" is not a decision factor when using MSAL Python.

For this, I read in the documentation that I should use PKCE.

Which doc did you read? It is probably not MSAL Python's doc.

invalid_client - AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.

When you registered your redirect_uri as a web platform (and rightfully so), you do have to also provision a client secret or a client certificate. (We do have more advanced pattern to allow a confidential client to federate by a managed identity, but it is still conceptually a confidential client.)

Thank you for the fast reply.

No. Based on OAuth2's client type definition, a (flask or not) webapp is typically a confidential client.

But if I suppose my python webapp cannot store secrets like an SPA, can't I consider my webapp as a public client?

Which doc did you read? It is probably not MSAL Python's doc.

I saw this solution was implemented for SPA.

In my case, I have users that creates different flask webapps. I would like to provide them with a common app registration which allows users to authenticate. For that, I would prefer not sharing the client secret.

Which doc did you read? It is probably not MSAL Python's doc.

I saw this [PKCE] solution was implemented for SPA.

Indeed, that is not the document for MSAL Python. That doc is for your SPA written in Javascript. It mentions PKCE because the MSAL.js library requires callers to explicitly write PKCE-relevant code. But (1) you won't use Python to write your SPA, and (2) MSAL Python automatically supports PKCE, so that doc is not applicable to MSAL Python anyway.

But if I suppose my python webapp cannot store secrets like an SPA, can't I consider my webapp as a public client?

No, your SPA will be written in Javascript. The web server hosting the js files of your SPA does not need authentication at all. You may use any web-hosting http server for that purpose, such as python -m http.server.

If you choose to reuse the same client id for your confidential web app, then the web app will need its secret or certificate etc.