Feature: Add admin-only SSO bridge to web UI
Bridge an already-authenticated portal session into a YAMA web session via a new /sso endpoint, so portal administrators can enter the remote-desktop UI without a second login. Only the "admin" portal role is bridged; any other role (viewer, unknown) still falls back to the built-in login form, so a low-privileged portal account cannot bypass authentication. - wsauth: extract IssueToken from VerifyLogin so an out-of-band-authenticated identity (SSO) can mint a session token without the challenge/response. - web: add the SSODetector interface, a fail-closed JWT detector (HMAC-only), and the /sso handler gated to the admin role. - cmd: enable the JWT detector via YAMA_SSO_JWT_SECRET, the shared HS256 secret matching the parent portal. - web UI: attempt SSO before showing the login form, falling back to login when the server returns 401. - docs: document SSO (admin-only) and license trial-vs-paid troubleshooting in README and the env example. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
d2149851b2
commit
53b7151fb7
9 files changed
+499
-11
No files matched your search
@@ -32,6 +32,7 @@ type Server struct {
|
||||
loginUserLimit *wsauth.RateLimiter
|
||||
trustForwardedFor bool // honor X-Forwarded-For (behind trusted proxy only)
|
||||
basePath string // web UI mount prefix (e.g. "/remoter"); "" = domain root
|
||||
sso SSODetector // nil = SSO disabled
|
||||
}
|
||||
|
||||
// Config tunes the server's exposed-on-public-HTTPS hardening knobs.
|
||||
@@ -60,6 +61,10 @@ type Config struct {
|
||||
// https://example.com/remoter). Must be empty or a leading-slash,
|
||||
// no-trailing-slash path; "" (default) serves from the domain root.
|
||||
BasePath string
|
||||
// SSO is an optional detector that maps an already-authenticated portal
|
||||
// session (cookie/header) into a YAMA web session via /sso. nil disables
|
||||
// SSO and the front-end falls back to the built-in login form.
|
||||
SSO SSODetector
|
||||
}
|
||||
|
||||
// New creates an HTTP server bound to the given port. port=0 disables the server.
|
||||
@@ -77,6 +82,7 @@ func (s *Server) WithConfig(cfg Config) *Server {
|
||||
s.loginUserLimit = cfg.LoginUserLimit
|
||||
s.trustForwardedFor = cfg.TrustForwardedFor
|
||||
s.basePath = cfg.BasePath
|
||||
s.sso = cfg.SSO
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -98,6 +104,7 @@ func (s *Server) Start() error {
|
||||
mux.HandleFunc("/health", s.handleHealth)
|
||||
mux.HandleFunc("/manifest.json", s.handleManifest)
|
||||
mux.HandleFunc("/api/devices", s.requireBearer(s.handleDevices))
|
||||
mux.HandleFunc("/sso", s.handleSSO)
|
||||
mux.HandleFunc("/ws", s.ws.serve)
|
||||
mux.HandleFunc("/static/xterm.js", staticHandler(xtermJS, "application/javascript; charset=utf-8"))
|
||||
mux.HandleFunc("/static/xterm.css", staticHandler(xtermCSS, "text/css; charset=utf-8"))
|
||||
|
||||
Reference in new issue
Block a user