Skip to content

[ZEPPELIN-6521] Preserve withCredentials on HTTP requests in production builds - #5377

Open
big-cir wants to merge 1 commit into
apache:masterfrom
big-cir:ZEPPELIN-6521
Open

[ZEPPELIN-6521] Preserve withCredentials on HTTP requests in production builds#5377
big-cir wants to merge 1 commit into
apache:masterfrom
big-cir:ZEPPELIN-6521

Conversation

@big-cir

@big-cir big-cir commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

What is this PR for?

In production builds the interceptor re-clones from the original httpRequest when it adds X-Requested-With, discarding the withCredentials: true clone made one line earlier. clone() inherits from whatever it was cloned from (update.withCredentials ?? this.withCredentials), so the production request goes out with the default false.

       let httpRequestUpdated = httpRequest.clone({ withCredentials: true });
       if (environment.production) {
-        httpRequestUpdated = httpRequest.clone({ setHeaders: { 'X-Requested-With': 'XMLHttpRequest' } });
+        httpRequestUpdated = httpRequestUpdated.clone({ setHeaders: { 'X-Requested-With': 'XMLHttpRequest' } });
       }

Two things the ticket does not cover. First, BaseUrlService builds the REST base from location, so every call to Zeppelin's own API is same-origin and the browser attaches cookies whether or not the flag is set; the flag has no reachable effect on those calls today. The classic UI's equivalent service remaps the port when the UI is served from the grunt dev server (zeppelin-web/src/components/base-url/base-url.service.js:26-29), which is what made withCredentials meaningful there, and the new UI has no such path. So this is a correctness fix — the interceptor now applies both of its settings consistently across builds, the way the classic UI does (zeppelin-web/src/app/app.js:78 and :161-163) — rather than a behaviour fix for API traffic. The second is the subject of the next section.

Scope and related issues

Third-party URL fetches go through this interceptor too, and this change narrows what they can reach. NoteImportComponent passes a user-supplied URL straight to HttpClient (note-import.component.ts:49), so the "import note from URL" request carries the same withCredentials and X-Requested-With as a call to Zeppelin's own API. A browser rejects a credentialed cross-origin response whose Access-Control-Allow-Origin is *, and that wildcard is what public file hosts serve.

Measured in Chromium against local servers reproducing each CORS configuration, with the raw.githubusercontent.com preflight response checked directly:

target host dev build production today production after this PR
rejects X-Requested-With at preflight — raw.githubusercontent.com answers the preflight with 403 blocked blocked blocked
allows X-Requested-With, serves Access-Control-Allow-Origin: * blocked works blocked

Only the second row changes, and it changes production to match what development already does, which is what this ticket asks for.

The underlying problem is that the interceptor does not distinguish Zeppelin's own API from an arbitrary URL. The classic UI handles it by overriding withCredentials: false for exactly this request (zeppelin-web/src/components/note-import/note-import.controller.js:95-97); the new UI has no equivalent. That is a separate defect which predates this ticket and already breaks the feature in development builds today.

Scoping the interceptor so that withCredentials and X-Requested-With are applied only to Zeppelin's own API would resolve it, and would not change anything this PR does for API calls. I have not filed a ticket for it yet — I would rather hear whether that scoping belongs in this PR or in a follow-up.

What type of PR is it?

Bug Fix

Todos

  • - Derive the production clone from the already-credentialed request
  • - Confirm X-Requested-With is still added in production builds
  • - Confirm development builds are unaffected

What is the Jira issue?

How should this be tested?

There is no unit-test runner for this app to add a spec to: the zeppelin project in angular.json declares only build, serve, extract-i18n and lint, and zeppelin-web-angular/src contains no .spec.ts. A Playwright test is also a poor fit here, because the local suite runs against ng serve (playwright.config.js:16), where environment.production is false and the affected branch never executes — such a test would pass with or without this change unless run in CI mode. The change was verified three other ways instead.

1. Lint

cd zeppelin-web-angular && npm run lint

Exit 0. 15 pre-existing member-ordering warnings in projects/zeppelin-visualization, none in the changed file; lint:react clean; prettier --check reports all files formatted.

2. HttpRequest.clone() inheritance, using the real class

Running both the old and the new form of the production branch through Angular's real HttpRequest class:

development branch    withCredentials=true   X-Requested-With=(none)
production, before    withCredentials=false  X-Requested-With=XMLHttpRequest
production, after     withCredentials=true   X-Requested-With=XMLHttpRequest

3. Production bundle in a real browser

ng build --configuration production twice — once with this commit and once with it reverted, changing nothing else — serving dist/zeppelin statically and instrumenting the XMLHttpRequest.prototype.withCredentials setter. BaseUrlService derives the REST base from location, so the app issues its normal bootstrap calls against the static server; they 404, but Angular assigns withCredentials before send(), which is what is being observed.

                      API requests   withCredentials assignments   X-Requested-With
before this commit    4              []                            XMLHttpRequest
after  this commit    4              [true, true, true, true]      XMLHttpRequest

X-Requested-With is present in both runs, which confirms the production branch really executed and that the change does not drop the header.

Screenshots (if appropriate)

N/A

Questions:

  • Does the license files need to update? No
  • Is there breaking changes for older versions? No — see "Scope and related issues" for the one behaviour that changes for third-party URL fetches
  • Does this needs documentation? No

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant