mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
feat(authentication): add a --no-auth flag to disable authentication (#553)
This commit is contained in:
parent
779fcf8e7f
commit
10f7744a62
16 changed files with 203 additions and 191 deletions
|
@ -29,6 +29,7 @@ func (*Service) ParseFlags(version string) (*portainer.CLIFlags, error) {
|
|||
Assets: kingpin.Flag("assets", "Path to the assets").Default(defaultAssetsDirectory).Short('a').String(),
|
||||
Data: kingpin.Flag("data", "Path to the folder where the data is stored").Default(defaultDataDirectory).Short('d').String(),
|
||||
Templates: kingpin.Flag("templates", "URL to the templates (apps) definitions").Default(defaultTemplatesURL).Short('t').String(),
|
||||
NoAuth: kingpin.Flag("no-auth", "Disable authentication").Default(defaultNoAuth).Bool(),
|
||||
TLSVerify: kingpin.Flag("tlsverify", "TLS support").Default(defaultTLSVerify).Bool(),
|
||||
TLSCacert: kingpin.Flag("tlscacert", "Path to the CA").Default(defaultTLSCACertPath).String(),
|
||||
TLSCert: kingpin.Flag("tlscert", "Path to the TLS certificate file").Default(defaultTLSCertPath).String(),
|
||||
|
|
|
@ -7,6 +7,7 @@ const (
|
|||
defaultDataDirectory = "/data"
|
||||
defaultAssetsDirectory = "."
|
||||
defaultTemplatesURL = "https://raw.githubusercontent.com/portainer/templates/master/templates.json"
|
||||
defaultNoAuth = "false"
|
||||
defaultTLSVerify = "false"
|
||||
defaultTLSCACertPath = "/certs/ca.pem"
|
||||
defaultTLSCertPath = "/certs/cert.pem"
|
||||
|
|
|
@ -5,6 +5,7 @@ const (
|
|||
defaultDataDirectory = "C:\\data"
|
||||
defaultAssetsDirectory = "."
|
||||
defaultTemplatesURL = "https://raw.githubusercontent.com/portainer/templates/master/templates.json"
|
||||
defaultNoAuth = "false"
|
||||
defaultTLSVerify = "false"
|
||||
defaultTLSCACertPath = "C:\\certs\\ca.pem"
|
||||
defaultTLSCertPath = "C:\\certs\\cert.pem"
|
||||
|
|
|
@ -25,8 +25,9 @@ func main() {
|
|||
}
|
||||
|
||||
settings := &portainer.Settings{
|
||||
HiddenLabels: *flags.Labels,
|
||||
Logo: *flags.Logo,
|
||||
HiddenLabels: *flags.Labels,
|
||||
Logo: *flags.Logo,
|
||||
Authentication: !*flags.NoAuth,
|
||||
}
|
||||
|
||||
fileService, err := file.NewService(*flags.Data, "")
|
||||
|
@ -41,9 +42,12 @@ func main() {
|
|||
}
|
||||
defer store.Close()
|
||||
|
||||
jwtService, err := jwt.NewService()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
var jwtService portainer.JWTService
|
||||
if !*flags.NoAuth {
|
||||
jwtService, err = jwt.NewService()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
var cryptoService portainer.CryptoService = &crypto.Service{}
|
||||
|
@ -76,6 +80,7 @@ func main() {
|
|||
AssetsPath: *flags.Assets,
|
||||
Settings: settings,
|
||||
TemplatesURL: *flags.Templates,
|
||||
AuthDisabled: *flags.NoAuth,
|
||||
UserService: store.UserService,
|
||||
EndpointService: store.EndpointService,
|
||||
CryptoService: cryptoService,
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
type AuthHandler struct {
|
||||
*mux.Router
|
||||
Logger *log.Logger
|
||||
authDisabled bool
|
||||
UserService portainer.UserService
|
||||
CryptoService portainer.CryptoService
|
||||
JWTService portainer.JWTService
|
||||
|
@ -26,6 +27,9 @@ const (
|
|||
ErrInvalidCredentialsFormat = portainer.Error("Invalid credentials format")
|
||||
// ErrInvalidCredentials is an error raised when credentials for a user are invalid
|
||||
ErrInvalidCredentials = portainer.Error("Invalid credentials")
|
||||
// ErrAuthDisabled is an error raised when trying to access the authentication endpoints
|
||||
// when the server has been started with the --no-auth flag
|
||||
ErrAuthDisabled = portainer.Error("Authentication is disabled")
|
||||
)
|
||||
|
||||
// NewAuthHandler returns a new instance of AuthHandler.
|
||||
|
@ -44,6 +48,11 @@ func (handler *AuthHandler) handlePostAuth(w http.ResponseWriter, r *http.Reques
|
|||
return
|
||||
}
|
||||
|
||||
if handler.authDisabled {
|
||||
Error(w, ErrAuthDisabled, http.StatusServiceUnavailable, handler.Logger)
|
||||
return
|
||||
}
|
||||
|
||||
var req postAuthRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
Error(w, ErrInvalidJSON, http.StatusBadRequest, handler.Logger)
|
||||
|
|
|
@ -9,7 +9,8 @@ import (
|
|||
|
||||
// Service represents a service to manage HTTP middlewares
|
||||
type middleWareService struct {
|
||||
jwtService portainer.JWTService
|
||||
jwtService portainer.JWTService
|
||||
authDisabled bool
|
||||
}
|
||||
|
||||
func addMiddleware(h http.Handler, middleware ...func(http.Handler) http.Handler) http.Handler {
|
||||
|
@ -37,24 +38,26 @@ func (*middleWareService) middleWareSecureHeaders(next http.Handler) http.Handle
|
|||
// middleWareAuthenticate provides Authentication middleware for handlers
|
||||
func (service *middleWareService) middleWareAuthenticate(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var token string
|
||||
if !service.authDisabled {
|
||||
var token string
|
||||
|
||||
// Get token from the Authorization header
|
||||
tokens, ok := r.Header["Authorization"]
|
||||
if ok && len(tokens) >= 1 {
|
||||
token = tokens[0]
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
// Get token from the Authorization header
|
||||
tokens, ok := r.Header["Authorization"]
|
||||
if ok && len(tokens) >= 1 {
|
||||
token = tokens[0]
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
Error(w, portainer.ErrUnauthorized, http.StatusUnauthorized, nil)
|
||||
return
|
||||
}
|
||||
if token == "" {
|
||||
Error(w, portainer.ErrUnauthorized, http.StatusUnauthorized, nil)
|
||||
return
|
||||
}
|
||||
|
||||
err := service.jwtService.VerifyToken(token)
|
||||
if err != nil {
|
||||
Error(w, err, http.StatusUnauthorized, nil)
|
||||
return
|
||||
err := service.jwtService.VerifyToken(token)
|
||||
if err != nil {
|
||||
Error(w, err, http.StatusUnauthorized, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
type Server struct {
|
||||
BindAddress string
|
||||
AssetsPath string
|
||||
AuthDisabled bool
|
||||
UserService portainer.UserService
|
||||
EndpointService portainer.EndpointService
|
||||
CryptoService portainer.CryptoService
|
||||
|
@ -40,13 +41,15 @@ func (server *Server) updateActiveEndpoint(endpoint *portainer.Endpoint) error {
|
|||
// Start starts the HTTP server
|
||||
func (server *Server) Start() error {
|
||||
middleWareService := &middleWareService{
|
||||
jwtService: server.JWTService,
|
||||
jwtService: server.JWTService,
|
||||
authDisabled: server.AuthDisabled,
|
||||
}
|
||||
|
||||
var authHandler = NewAuthHandler()
|
||||
authHandler.UserService = server.UserService
|
||||
authHandler.CryptoService = server.CryptoService
|
||||
authHandler.JWTService = server.JWTService
|
||||
authHandler.authDisabled = server.AuthDisabled
|
||||
var userHandler = NewUserHandler(middleWareService)
|
||||
userHandler.UserService = server.UserService
|
||||
userHandler.CryptoService = server.CryptoService
|
||||
|
|
|
@ -20,6 +20,7 @@ type (
|
|||
Labels *[]Pair
|
||||
Logo *string
|
||||
Templates *string
|
||||
NoAuth *bool
|
||||
TLSVerify *bool
|
||||
TLSCacert *string
|
||||
TLSCert *string
|
||||
|
@ -28,8 +29,9 @@ type (
|
|||
|
||||
// Settings represents Portainer settings.
|
||||
Settings struct {
|
||||
HiddenLabels []Pair `json:"hiddenLabels"`
|
||||
Logo string `json:"logo"`
|
||||
HiddenLabels []Pair `json:"hiddenLabels"`
|
||||
Logo string `json:"logo"`
|
||||
Authentication bool `json:"authentication"`
|
||||
}
|
||||
|
||||
// User represent a user account.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue