Skip to content

Trusted-header (reverse-proxy SSO) authentication for the web panel, opt-in - #167

Open
alynes wants to merge 1 commit into
Sathvik-Rao:mainfrom
dvoid-io:patch/trusted-header-auth
Open

Trusted-header (reverse-proxy SSO) authentication for the web panel, opt-in#167
alynes wants to merge 1 commit into
Sathvik-Rao:mainfrom
dvoid-io:patch/trusted-header-auth

Conversation

@alynes

@alynes alynes commented Aug 14, 2026

Copy link
Copy Markdown

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 (default false) + CC_TRUSTED_HEADER_NAME (default X-Remote-User), following the existing CC_* property idiom and surfaced in the admin panel's properties view.
  • When enabled, a request carrying the header is authenticated as that user without the login form. Unknown or disabled users fall through to the normal login flow.
  • Native clients are untouched: /login, /logout, /clipsocket, /p2psignaling are 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)

  • The filter emits the same UsernamePasswordAuthenticationToken/UserPrincipal pair as form login, so the STOMP principal cast in ClipCascadeController, isAdmin() checks, and /whoami behave identically — no controller changes.
  • It checks isEnabled() only, never isAccountNonLocked() — that method feeds the brute-force tracker and would count each SSO request as a failed attempt.
  • The SecurityContext is 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 (/whoami correct role), session persists without the header, no header → login redirect, unknown user → login redirect, /login still 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.

… 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.
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