feat: add OIDC authentication for server mode

This commit is contained in:
2026-04-01 19:33:15 +02:00
parent 7bce56384f
commit 52a975b66d
13 changed files with 515 additions and 7 deletions

View File

@@ -9,8 +9,10 @@ import (
)
// New returns an HTTP handler that exposes NodeService as a JSON API.
// Every request must supply an X-Ax-User header identifying the acting user.
func New(newSvc func(user string) (service.NodeService, error)) http.Handler {
// When oidcCfg is non-nil, every request must carry a valid Bearer token;
// the authenticated username is derived from the token claim configured in
// OIDCConfig.UserClaim. Without OIDC, the X-Ax-User header is used instead.
func New(newSvc func(user string) (service.NodeService, error), oidcCfg *service.OIDCConfig) (http.Handler, error) {
s := &server{newSvc: newSvc}
mux := http.NewServeMux()
mux.HandleFunc("GET /nodes", s.listNodes)
@@ -20,7 +22,17 @@ func New(newSvc func(user string) (service.NodeService, error)) http.Handler {
mux.HandleFunc("DELETE /nodes/{id}", s.deleteNode)
mux.HandleFunc("GET /users", s.listUsers)
mux.HandleFunc("POST /users", s.addUser)
return mux
if oidcCfg != nil {
ah, err := newAuthHandler(*oidcCfg)
if err != nil {
return nil, err
}
mux.HandleFunc("POST /auth/start", ah.start)
mux.HandleFunc("GET /auth/callback", ah.callback)
mux.HandleFunc("GET /auth/poll", ah.poll)
return withSessionAuth(ah, mux), nil
}
return mux, nil
}
type server struct {
@@ -28,7 +40,10 @@ type server struct {
}
func (s *server) svc(w http.ResponseWriter, r *http.Request) (service.NodeService, bool) {
user := r.Header.Get("X-Ax-User")
user := userFromContext(r)
if user == "" {
user = r.Header.Get("X-Ax-User")
}
if user == "" {
writeError(w, http.StatusUnauthorized, "X-Ax-User header required")
return nil, false