Skip to content

Suppress Basic challenge on z/OSMF API 401s for XHR clients (#119)#120

Merged
mgrossmann merged 1 commit into
mainfrom
issue-119-suppress-basic-challenge-on-xhr
Jul 6, 2026
Merged

Suppress Basic challenge on z/OSMF API 401s for XHR clients (#119)#120
mgrossmann merged 1 commit into
mainfrom
issue-119-suppress-basic-challenge-on-xhr

Conversation

@mgrossmann

Copy link
Copy Markdown
Contributor

Problem

httpd returned WWW-Authenticate: Basic realm="MVS" on every 401, including XHR/fetch calls from the mvsMF SPA. Browsers respond to that header by popping their native credential dialog, and the Basic credentials the browser then caches:

  1. shadow the SPA's own 401 handling (the dialog intercepts before the JS sees the 401), and
  2. outlive the token session — they survive the SPA's token logout (DELETE /zosmf/services/authenticate), re-introducing browser-side Basic credentials and defeating the token model from Auth 6/6 (mvsMF SPA): token login; stop storing the password mvsmf#161.

Change

src/httppc.c (auth_required_response): omit the WWW-Authenticate line when the request carries the z/OSMF CSRF marker X-CSRF-ZOSMF-HEADER. Such clients are programmatic/XHR and handle the bare 401 themselves. The rest of the 401 (status, Cache-Control: no-store, body) is unchanged.

  • Genuine Basic clients (curl -u, Zowe) send credentials preemptively and never needed the challenge.
  • A plain browser navigation with no marker still receives the challenge (e.g. a static AUTH=BASIC area keeps its intended popup).
  • FORM routes are untouched.

The env lookup is caseless (http_find_envhttp_cmp), so the marker matches regardless of header casing.

Sample parmlib

samplib/httpprm0: add two exact AUTH=NONE routes before the gated /zosmf/* catch-all (first match wins):

  • /zosmf/info — the SPA's anonymous reachability probe gets a clean 200.
  • /zosmf/services/authenticate — the token login/logout endpoint does its own auth; the gate must not challenge it.

Design note

This does not mirror stock z/OSMF — verified empirically that real z/OSMF does send WWW-Authenticate: Basic on its REST API 401s (and ignores X-CSRF-ZOSMF-HEADER). This is a deliberate improvement for our token-based SPA, not a compatibility claim.

The cleaner long-term model — separating credential source (accept Basic) from challenge presentation (advertise Basic) via a per-route API marker — is filed as a follow-up under the auth-redesign cleanup (#105).

Verification

  • Host compile of src/httppc.c with cc370 -S clean (no warnings on the changed file); the HTTP_X-CSRF-ZOSMF-HEADER literal confirmed present in the generated assembly.
  • make compiledb regenerated (122 entries).

To verify on the live MVS system

  • With X-CSRF-ZOSMF-HEADER present, a /zosmf/* 401 returns no WWW-Authenticate (bare 401); without it, the challenge is still sent.
  • Confirm the mvsMF SPA no longer pops the native dialog on token expiry, and that Basic credentials no longer survive token logout.

Fixes #119

httpd returned WWW-Authenticate: Basic on every 401, including XHR/fetch
calls from the mvsMF SPA. Browsers respond to that header by popping their
native credential dialog, whose cached Basic credentials then outlive the
token session and survive token logout -- re-introducing browser-side Basic
credentials and defeating the SPA's token model.

Omit the challenge when the request carries the z/OSMF CSRF marker
(X-CSRF-ZOSMF-HEADER): such clients are programmatic/XHR and handle the bare
401 themselves. Genuine Basic clients (curl -u, Zowe) send credentials
preemptively; a plain browser navigation with no marker still receives it.

Also mark /zosmf/info and /zosmf/services/authenticate AUTH=NONE (before the
gated /zosmf/* catch-all) in the sample parmlib: the anonymous reachability
probe and the token login/logout endpoint do their own auth.

Fixes #119
@mgrossmann
mgrossmann merged commit 323d3a4 into main Jul 6, 2026
1 check passed
@mgrossmann
mgrossmann deleted the issue-119-suppress-basic-challenge-on-xhr branch July 6, 2026 15:17
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.

Auth: suppress WWW-Authenticate: Basic on z/OSMF API 401 (native browser popup shadows token logout)

1 participant