Trusted-header (reverse-proxy SSO) authentication for the web panel, opt-in - #167
Open
alynes wants to merge 1 commit into
Open
Trusted-header (reverse-proxy SSO) authentication for the web panel, opt-in#167alynes wants to merge 1 commit into
alynes wants to merge 1 commit into
Conversation
… panel Opt-in via CC_TRUSTED_HEADER_AUTH (default false) + CC_TRUSTED_HEADER_NAME (default X-Remote-User): an authenticating reverse proxy that strips client-supplied copies of the header and injects its own can sign users into the web panel without the login form — the standard self-hosted SSO pattern (Authelia, oauth2-proxy, CDN workers). Native clients are untouched: /login, /logout, /clipsocket and /p2psignaling are excluded from the filter and keep username/password + session auth exactly as today. Design notes: - Emits the same UsernamePasswordAuthenticationToken/UserPrincipal pair as form login, so the STOMP principal cast, isAdmin() checks and /whoami behave identically. - Checks isEnabled() only — never isAccountNonLocked(), which feeds the brute-force tracker and would count SSO requests as failed attempts. - Persists the SecurityContext to the session (Spring Security 6 no longer auto-saves), so the user lookup runs once per session. - Unknown/disabled users fall through to the normal login flow. 77 lines: one new filter, two @value properties (surfaced in the admin panel's properties view via toString), one addFilterBefore.
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.
Adds opt-in reverse-proxy SSO for the web panel only — the pattern self-hosters use with Authelia, Authentik, oauth2-proxy, or a CDN worker: the proxy authenticates the user, strips any client-supplied identity header, and injects its own. This follows up the SSO discussion in #25 as the much smaller alternative to full OIDC: no client changes, no new dependencies, ~77 lines, off by default.
Behavior
CC_TRUSTED_HEADER_AUTH(defaultfalse) +CC_TRUSTED_HEADER_NAME(defaultX-Remote-User), following the existingCC_*property idiom and surfaced in the admin panel's properties view./login,/logout,/clipsocket,/p2psignalingare excluded from the filter and keep username/password + session auth exactly as today — consistent with the reverse-proxy bypass list already documented for SSO setups.Design notes (things that bit during testing)
UsernamePasswordAuthenticationToken/UserPrincipalpair as form login, so the STOMP principal cast inClipCascadeController,isAdmin()checks, and/whoamibehave identically — no controller changes.isEnabled()only, neverisAccountNonLocked()— that method feeds the brute-force tracker and would count each SSO request as a failed attempt.SecurityContextis persisted to the session explicitly (Spring Security 6 no longer auto-saves), so the user lookup runs once per session, not per request.Security
Only safe when the server is reachable exclusively through the authenticating proxy — documented prominently on the property and in the filter's javadoc. With the flag off (the default), the filter body never runs.
Tested
Live container matrix on this branch's build: header → authenticated (
/whoamicorrect role), session persists without the header, no header → login redirect, unknown user → login redirect,/loginstill serves the form with the header present, form login byte-identical (client-side sha3 + CSRF flow), flag off → header ignored.Happy to adjust naming, split the properties, or rebase as you prefer.