microsoft-authentication-library-for-python icon indicating copy to clipboard operation
microsoft-authentication-library-for-python copied to clipboard

[Feature Request] Origin header missing on SPA token request

Open JeffreyStevens opened this issue 2 years ago • 9 comments

When using the interactive_sample.py for my Azure AD FS server using the PKCE flow, the oauth2.py method _obtain_token() does not inject an Origin header as required by our Application tenant token endpoint, so I wound up hardcoding an origin header with a value of http://localhost:8000 just to get it to work. Could this be made a configuration value?

Also, it would be nice if the browser tab opened by authcode.py method _browse could be closed on success so as not to annoy users.

JeffreyStevens avatar Dec 19 '23 14:12 JeffreyStevens

When using the interactive_sample.py for my Azure AD FS server using the PKCE flow, ... inject an Origin header as required by our Application tenant token endpoint

AFAIK, PKCE specs does not require an Origin header. Where does that requirement come from? Is it a special requirement only needed for that AD FS server? Does that server also require Origin even when not using PKCE? We need more info to understand how/whether to support this case.

rayluo avatar Dec 19 '23 17:12 rayluo

I'll have to ask one of our Principal engineers about it, but it does appear to be the token endpoint call returns a

AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests.

error and it goes away if I add the Origin header. It may not be related to PKCE, I just noticed that term in the code at the obtain_token_by_browser() method. I should probably add I'm using an AD application registration for a SPA application that I own, not a new one specifically for this Python code.

JeffreyStevens avatar Dec 19 '23 22:12 JeffreyStevens

Quick question to @JeffreyStevens . If you hardcode an origin header with the string null, will it still work?

rayluo avatar Dec 20 '23 02:12 rayluo

It does not, returns Token acquisition failed. Here is the code mod:

Screenshot 2023-12-20 at 7 23 35 AM

JeffreyStevens avatar Dec 20 '23 12:12 JeffreyStevens

I should probably add I'm using an AD application registration for a SPA application that I own, not a new one specifically for this Python code - this is probably the culprit. Only MSAL JS supports the SPA scenario and while I am not an expert, it does deal with cross origin and other browser-y aspects.

Pls create a new app reg. Feel free to use a personal tenant if just for testing.

bgavrilMS avatar Dec 20 '23 13:12 bgavrilMS

I have gotten MSAL JS working as you mentioned. I'm new to Python as I have a new job so I'm trying to replicate oauth flows I had working in JS. Would you consider adding a configuration option for this anyway?

JeffreyStevens avatar Dec 20 '23 14:12 JeffreyStevens

Quick question to @JeffreyStevens . If you hardcode an origin header with the string null, will it still work?

It does not, returns Token acquisition failed. Here is the code mod:

No, I said "string null". Try _header['Origin'] = "null" and see how that goes.

rayluo avatar Dec 20 '23 15:12 rayluo

What magic is this?! Interactive works with "null"! On the downside, I think it breaks the confidential_client_secret_sample.py because that fails unless I remove the Origin header. So, this makes both work.

Screenshot 2023-12-20 at 9 41 48 PM

JeffreyStevens avatar Dec 21 '23 02:12 JeffreyStevens

What magic is this?! Interactive works with "null"! On the downside, I think it breaks the confidential_client_secret_sample.py because that fails unless I remove the Origin header.

I cannot reproduce it breaking confidential_client_secret_sample. Perhaps you would like to double check?

Regardless, the null was just an experiment. More time will be needed to evaluate different options. We will probably need to wait until many of my colleagues return from their holiday vacation.

Meanwhile, @JeffreyStevens you already have a workaround, and ideally you shall consider using a non-SPA app for your Python script, so that you won't run into this issue in the first place.

rayluo avatar Dec 21 '23 03:12 rayluo