code: func NewAuthenticator(router *mux.Router, ctx *Settings, log logging.Logger) AuthenticatorAPI {
  	a := &authenticator{
  		router: router,
  		log:    log,
  		formatter: render.New(render.Options{
  			IndentJSON: true,
  		}),
  		groupDb: make(map[string][]*access.PermissionGroup_Permissions),
  		expTime: ctx.ExpTime,
  	}
  
  	// Authentication store
  	if ctx.AuthStore != nil {
  		a.userDb = ctx.AuthStore
  	} else {
  		a.userDb = CreateDefaultAuthDB()
  	}
  
  	// Set token signature
  	signature = ctx.Signature
  	if a.expTime == 0 {
  		a.expTime = defaultExpTime
  		a.log.Debugf("Token expiration time claim not set, defaulting to 1 hour")
  	}
  
  	// Hash of default admin password, hashed with cost 10
  	hash := "$2a$10$q5s1LP7xbCJWJlLet1g/h.rGrsHtciILps90bNRdJ.6DRekw9b.zK"
  	if err := a.userDb.AddUser(admin, hash, []string{admin}); err != nil {
  		a.log.Errorf("failed to add admin user: %v", err)
  	}
  
  	for _, user := range ctx.Users {
  		if user.Name == admin {
  			a.log.Errorf("rejected to create user-defined account named 'admin'")
  			continue
  		}
  		if err := a.userDb.AddUser(user.Name, user.PasswordHash, user.Permissions); err != nil {
  			a.log.Errorf("failed to add user %s: %v", user.Name, err)
  			continue
  		}
  		a.log.Debug("Registered user %s, permissions: %v", user.Name, user.Permissions)
  	}
  
  	// Admin-group, available by default and always enabled for all URLs
  	a.groupDb[admin] = []*access.PermissionGroup_Permissions{}
  
  	a.registerSecurityHandlers()
  
  	return a
  }
docs: // NewAuthenticator prepares new instance of authenticator.