1
0
Fork 0
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:
Anthony Lapenna 2017-02-01 22:13:48 +13:00 committed by GitHub
parent 779fcf8e7f
commit 10f7744a62
16 changed files with 203 additions and 191 deletions

View file

@ -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(),

View file

@ -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"

View file

@ -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"

View file

@ -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,

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

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