Crystal HTTP::Client and OAuth2 middleware integration for automatic 401 WWW-Authenticate handling
0 reputation · 27 May 2024, 16:09 UTC
0 reputation · 27 May 2024, 16:09 UTC
When a Crystal HTTP::Client receives a 401 Unauthorized response that includes a WWW‑Authenticate header after a successful TLS handshake, the standard library does not automatically retry the request with refreshed credentials. Developers must decide whether to propagate the error, invoke custom middleware, or implement a retry loop that extracts the challenge and obtains a new token from a vault or secret store.
The goal is to define a clear, least‑privilege‑aware integration point between HTTP::Client and credential‑refresh mechanisms that works across fiber‑shared clients without leaking headers or requiring per‑fiber client duplication. Constraints include the absence of built‑in token‑lifecycle callbacks, the need to keep TLS verification settings intact, and the requirement that any retry logic does not inadvertently resend BasicAuth in cleartext over non‑TLS connections.
What should be the default behavior of HTTP::Client when a 401 with WWW‑Authenticate is observed? Should the library provide an optional on_auth_challenge callback, or is it preferable to leave error handling entirely to application‑level middleware? How can least‑privilege credential scopes be enforced when retrying requests across fibers that share a single client instance?
35775 reputation · 28 May 2024, 03:49 UTC
Default behavior: HTTP::Client should propagate a 401 Unauthorized with WWW-Authenticate unchanged to the caller and not retry automatically. The stdlib provides no built-in on_auth_challenge callback or token lifecycle hooks. Automatic retry inside the library would be unsafe with the stated constraints around TLS verification and BasicAuth leakage.
Integration point: application-level middleware, not stdlib. Keep the client immutable and shared across fibers. Supply Authorization per request from a fiber-local token provider. Retry once after a 401 only when the connection is TLS verified and the challenge scheme is acceptable.
Automatic retry in stdlib would need to decide when a 401 is transient, which auth scheme to use, and whether the connection is safe for credential resend. Those decisions are application policy, not transport policy. Keeping retry in app code preserves least-privilege scoping and avoids resending BasicAuth over non-TLS.
Assumption and uncertainty: stdlib behavior is version-sensitive. No current verification of a specific Crystal release is available here. Do not assume undocumented auth hooks exist.
One diagnostic detail that changes the recommendation: Is Authorization currently set as a default header on the shared HTTP::Client instance, or is it injected per request? If it is a client default, the client must be refactored to per-request headers before any safe retry logic can be added.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.