shdsbilling/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/server.go

183 lines
4.7 KiB
Go

package auth
import (
"context"
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/rancher/norman/store/proxy"
"github.com/rancher/rancher/pkg/api/norman"
"github.com/rancher/rancher/pkg/auth/api"
"github.com/rancher/rancher/pkg/auth/data"
"github.com/rancher/rancher/pkg/auth/providerrefresh"
"github.com/rancher/rancher/pkg/auth/providers/common"
"github.com/rancher/rancher/pkg/auth/providers/publicapi"
"github.com/rancher/rancher/pkg/auth/providers/saml"
"github.com/rancher/rancher/pkg/auth/requests"
"github.com/rancher/rancher/pkg/auth/tokens"
"github.com/rancher/rancher/pkg/clusterrouter"
"github.com/rancher/rancher/pkg/features"
"github.com/rancher/rancher/pkg/types/config"
steveauth "github.com/rancher/steve/pkg/auth"
"github.com/sirupsen/logrus"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/rest"
)
type Server struct {
Authenticator steveauth.Middleware
Management func(http.Handler) http.Handler
scaledContext *config.ScaledContext
}
func NewAlwaysAdmin() (*Server, error) {
return &Server{
Authenticator: steveauth.ToMiddleware(steveauth.AuthenticatorFunc(steveauth.AlwaysAdmin)),
Management: func(next http.Handler) http.Handler {
return next
},
}, nil
}
func NewHeaderAuth() (*Server, error) {
return &Server{
Authenticator: steveauth.ToMiddleware(steveauth.AuthenticatorFunc(steveauth.Impersonation)),
Management: func(next http.Handler) http.Handler {
return next
},
}, nil
}
func NewServer(ctx context.Context, cfg *rest.Config) (*Server, error) {
sc, err := config.NewScaledContext(*cfg, nil)
if err != nil {
return nil, err
}
sc.UserManager, err = common.NewUserManagerNoBindings(sc)
if err != nil {
return nil, err
}
sc.ClientGetter, err = proxy.NewClientGetterFromConfig(*cfg)
if err != nil {
return nil, err
}
authenticator := requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, sc)
authManagement, err := newAPIManagement(ctx, sc)
if err != nil {
return nil, err
}
return &Server{
Authenticator: requests.ToAuthMiddleware(authenticator),
Management: authManagement,
scaledContext: sc,
}, nil
}
func newAPIManagement(ctx context.Context, scaledContext *config.ScaledContext) (steveauth.Middleware, error) {
privateAPI, err := newPrivateAPI(ctx, scaledContext)
if err != nil {
return nil, err
}
publicAPI, err := publicapi.NewHandler(ctx, scaledContext, norman.ConfigureAPIUI)
if err != nil {
return nil, err
}
saml := saml.AuthHandler()
root := mux.NewRouter()
root.UseEncodedPath()
root.PathPrefix("/v3-public").Handler(publicAPI)
root.PathPrefix("/v1-saml").Handler(saml)
root.NotFoundHandler = privateAPI
return func(next http.Handler) http.Handler {
privateAPI.NotFoundHandler = next
return root
}, nil
}
func newPrivateAPI(ctx context.Context, scaledContext *config.ScaledContext) (*mux.Router, error) {
tokenAPI, err := tokens.NewAPIHandler(ctx, scaledContext, norman.ConfigureAPIUI)
if err != nil {
return nil, err
}
otherAPIs, err := api.NewNormanServer(ctx, clusterrouter.GetClusterID, scaledContext)
if err != nil {
return nil, err
}
root := mux.NewRouter()
root.UseEncodedPath()
root.Use(requests.NewAuthenticatedFilter)
root.PathPrefix("/v3/identit").Handler(tokenAPI)
root.PathPrefix("/v3/token").Handler(tokenAPI)
root.PathPrefix("/v3/authConfig").Handler(otherAPIs)
root.PathPrefix("/v3/principal").Handler(otherAPIs)
root.PathPrefix("/v3/user").Handler(otherAPIs)
root.PathPrefix("/v3/schema").Handler(otherAPIs)
root.PathPrefix("/v3/subscribe").Handler(otherAPIs)
return root, nil
}
func (s *Server) OnLeader(ctx context.Context) error {
if s.scaledContext == nil {
return nil
}
management := &config.ManagementContext{
Management: s.scaledContext.Management,
Core: s.scaledContext.Core,
}
if err := data.AuthConfigs(management); err != nil {
return fmt.Errorf("failed to add authconfig data: %v", err)
}
tokens.StartPurgeDaemon(ctx, management)
providerrefresh.StartRefreshDaemon(ctx, s.scaledContext, management)
logrus.Infof("Steve auth startup complete")
return nil
}
func (s *Server) Start(ctx context.Context, leader bool) error {
if s.scaledContext == nil {
return nil
}
if err := s.scaledContext.Start(ctx); err != nil {
return err
}
if leader {
return s.OnLeader(ctx)
}
return nil
}
func SetXAPICattleAuthHeader(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if features.Auth.Enabled() {
user, ok := request.UserFrom(req.Context())
if ok {
ok = false
for _, group := range user.GetGroups() {
if group == "system:authenticated" {
ok = true
}
}
}
rw.Header().Set("X-API-Cattle-Auth", fmt.Sprint(ok))
} else {
rw.Header().Set("X-API-Cattle-Auth", "none")
}
next.ServeHTTP(rw, req)
})
}