fix(auth): restore AAD local emulator fallback and normalize openIdIssuer URL (#947)#995
Open
LongOddCode wants to merge 1 commit intoAzure:mainfrom
Open
Conversation
…suer URL (Azure#947) Fixes two regressions in the custom-auth AAD flow introduced by Azure#905 in 2.0.3: 1. `/.auth/login/aad` now returns a 400 "AAD_CLIENT_ID not found in env" in local dev, even though the pre-2.0.3 behaviour was to serve the local auth emulator. Restore the fallback: when the config references env vars but those env vars are unset, delegate to the SWA local auth emulator instead of hard-failing. Missing config fields still 400 as before. 2. An `openIdIssuer` of `https://login.microsoftonline.com/<tenant>/oauth2/v2.0` (accepted by the deployed SWA runtime) caused ERR_TOO_MANY_REDIRECTS during CLI OIDC discovery. Normalize the URL to the canonical `/v2.0` form in `OpenIdHelper` so one `staticwebapp.config.json` works both locally and deployed. Adds 17 unit tests covering both regressions. All 502 existing tests still pass. Refs: Azure#928, Azure#941, Azure#947, PR Azure#905
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two regressions in the custom-auth AAD flow were introduced in 2.0.3 by PR #905. Reported separately as #928, #941, and #947 — this PR fixes the common root causes.
Regression 1 —
/.auth/login/aadreturns 400 locallyBefore 2.0.3, running the CLI against a
staticwebapp.config.jsonthat declared an AAD custom-auth provider would serve the local auth emulator at/.auth/login/aadwhen the referenced env vars were not set. That behaviour is what makes local dev ergonomic: a developer can reuse the production config without provisioning a tenant.After 2.0.3,
checkCustomAuthConfigFieldshard-fails:…which breaks
swa startfor every user whose config targets AAD.Regression 2 —
/oauth2/v2.0issuer URL fails discoveryThe deployed SWA runtime accepts
https://login.microsoftonline.com/<tenant>/oauth2/v2.0as an alias for the canonicalhttps://login.microsoftonline.com/<tenant>/v2.0. The CLI’s OIDC discovery (viaopenid-client) does not — it follows redirects from<issuer>/.well-known/openid-configurationand ends up inERR_TOO_MANY_REDIRECTS. Users therefore need two differentopenIdIssuervalues (one for local, one for prod) which is what #947 describes.Root Cause
auth-login-provider-custom.ts→checkCustomAuthConfigFieldsopenidHelper.ts→OpenIdHelperctornew URL(issuerUrl)is passed directly toclient.discovery()without normalization, so a/oauth2/v2.0suffix breaks discovery.src/msha/auth/index.tsroutes/.auth/login/aadexclusively to the custom-auth handler whenisCustomAuth=true, so URL-level fallback is not possible — the delegation must happen in-process.Fix
src/core/utils/openidHelper.tsexport function normalizeOpenIdIssuer(url)that rewrites a trailing/oauth2/v2.0to/v2.0. Wire it into theOpenIdHelperconstructor beforenew URL(...). Coverslogin.microsoftonline.com,*.ciamlogin.com, and Entra custom URL domains.src/msha/auth/routes/auth-login-provider-custom.tsshouldFallbackToAadEmulator(providerName, customAuth)— returnstrueonly when provider isaad, the config declares both setting names, and at least one referenced env var is unset (i.e. clearly a local-dev case). Delegate toauthLoginProviderEmulatorinhttpTriggerbeforecheckCustomAuthConfigFields.Design notes:
checkCustomAuthConfigFieldsis unchanged. It is also used byauth-login-provider-callback.ts, which must keep strict 400 semantics — a callback with a real OAuth code has no legitimate reason to fall back to the emulator. Placing the pre-check in thehttpTriggercaller avoids coupling the two code paths.clientIdSettingNameorclientSecretSettingNameis missing from the config file entirely (as opposed to referenced-but-unset env vars), we fall through to the existing 400 response. Test case (e) covers this.Testing
All new and existing tests pass against Node 20.18.0.
New tests (17):
src/core/utils/openidHelper.spec.tsnormalizeOpenIdIssuercorrectness across tenant-id / common / organizations, ciamlogin.com, custom Entra domains, canonical URLs preserved, trailing slash preserved, unrelated URLs untouchedsrc/msha/auth/routes/auth-login-provider-custom.spec.tsManual repro of #947 locally:
staticwebapp.config.jsonwithopenIdIssuer=https://login.microsoftonline.com/<tenant>/oauth2/v2.0and env vars unset.GET /.auth/login/aad→ 400AAD_CLIENT_ID not found in env.GET /.auth/login/aad→ local auth emulator HTML (same as pre-2.0.3).References