cloudentity / oauth2c

User-friendly OAuth2 CLI
https://cloudentity.github.io/oauth2c/
Apache License 2.0
741 stars 29 forks source link

Add Origin header for Azure SPA authorization code flow with PKCE #108

Closed Sopka closed 4 months ago

Sopka commented 4 months ago

I was trying to use the authorization code flow with PKCE an no client secret to retreive an access token from Azure EntraID with a Single-page application (SPA) configured for the redirect URI back to oauth2 at http://localhost:9876/callback:

./oauth2c "https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0" \
  --pkce \
  --audience "api://myapp" \
  --client-id "${AZURE_CLIENT_ID}" \
  --response-types code \
  --response-mode query \
  --grant-type authorization_code \
  --auth-method none \
  --scopes "api://myapp/Some.Scope"

The error message from azure was: "AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests.

Apparently you have to include the Origin request header.

Initial hint from stackoverflow: https://stackoverflow.com/questions/61231144/getting-access-tokens-from-postman-tokens-issued-for-the-single-page-applicati

Also documented at microsoft: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#redirect-uri-setup-required-for-single-page-apps:

"Applications can't use a spa redirect URI with non-SPA flows, for example, native applications or client credential flows. To ensure security and best practices, the Microsoft identity platform returns an error if you attempt to use a spa redirect URI without an Origin header. Similarly, the Microsoft identity platform also prevents the use of client credentials in all flows in the presence of an Origin header, to ensure that secrets aren't used from within the browser."

This patch adds the necessary request header and with it my oauth2c command is able to retreive an access token. Since I am not a core maintainer of this project there might be issues with this patch and even a better way to implement it...