mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-10-30 23:45:06 +01:00 
			
		
		
		
	Add config option for expiration of sessions/tokens
This commit is contained in:
		
							
								
								
									
										18
									
								
								auth/auth.go
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								auth/auth.go
									
									
									
									
									
								
							| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/ClusterCockpit/cc-backend/log" | 	"github.com/ClusterCockpit/cc-backend/log" | ||||||
| 	sq "github.com/Masterminds/squirrel" | 	sq "github.com/Masterminds/squirrel" | ||||||
| @@ -60,6 +61,10 @@ type Authentication struct { | |||||||
|  |  | ||||||
| 	ldapConfig           *LdapConfig | 	ldapConfig           *LdapConfig | ||||||
| 	ldapSyncUserPassword string | 	ldapSyncUserPassword string | ||||||
|  |  | ||||||
|  | 	// If zero, tokens/sessions do not expire. | ||||||
|  | 	SessionMaxAge time.Duration | ||||||
|  | 	JwtMaxAge     time.Duration | ||||||
| } | } | ||||||
|  |  | ||||||
| func (auth *Authentication) Init(db *sqlx.DB, ldapConfig *LdapConfig) error { | func (auth *Authentication) Init(db *sqlx.DB, ldapConfig *LdapConfig) error { | ||||||
| @@ -208,7 +213,9 @@ func (auth *Authentication) Login(onsuccess http.Handler, onfailure func(rw http | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		session.Options.MaxAge = 30 * 24 * 60 * 60 | 		if auth.SessionMaxAge != 0 { | ||||||
|  | 			session.Options.MaxAge = int(auth.SessionMaxAge.Seconds()) | ||||||
|  | 		} | ||||||
| 		session.Values["username"] = user.Username | 		session.Values["username"] = user.Username | ||||||
| 		session.Values["roles"] = user.Roles | 		session.Values["roles"] = user.Roles | ||||||
| 		if err := auth.sessionStore.Save(r, rw, session); err != nil { | 		if err := auth.sessionStore.Save(r, rw, session); err != nil { | ||||||
| @@ -320,10 +327,15 @@ func (auth *Authentication) ProvideJWT(user *User) (string, error) { | |||||||
| 		return "", errors.New("environment variable 'JWT_PRIVATE_KEY' not set") | 		return "", errors.New("environment variable 'JWT_PRIVATE_KEY' not set") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tok := jwt.NewWithClaims(jwt.SigningMethodEdDSA, jwt.MapClaims{ | 	claims := jwt.MapClaims{ | ||||||
| 		"sub":   user.Username, | 		"sub":   user.Username, | ||||||
| 		"roles": user.Roles, | 		"roles": user.Roles, | ||||||
| 	}) | 	} | ||||||
|  | 	if auth.JwtMaxAge != 0 { | ||||||
|  | 		claims["exp"] = time.Now().Add(auth.JwtMaxAge).Unix() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tok := jwt.NewWithClaims(jwt.SigningMethodEdDSA, claims) | ||||||
|  |  | ||||||
| 	return tok.SignedString(auth.jwtPrivateKey) | 	return tok.SignedString(auth.jwtPrivateKey) | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								server.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								server.go
									
									
									
									
									
								
							| @@ -71,6 +71,12 @@ type ProgramConfig struct { | |||||||
| 	// For LDAP Authentication and user syncronisation. | 	// For LDAP Authentication and user syncronisation. | ||||||
| 	LdapConfig *auth.LdapConfig `json:"ldap"` | 	LdapConfig *auth.LdapConfig `json:"ldap"` | ||||||
|  |  | ||||||
|  | 	// Specifies for how long a session or JWT shall be valid | ||||||
|  | 	// as a string parsable by time.ParseDuration(). | ||||||
|  | 	// If 0 or empty, the session/token does not expire! | ||||||
|  | 	SessionMaxAge string `json:"session-max-age"` | ||||||
|  | 	JwtMaxAge     string `json:"jwt-max-age"` | ||||||
|  |  | ||||||
| 	// If both those options are not empty, use HTTPS using those certificates. | 	// If both those options are not empty, use HTTPS using those certificates. | ||||||
| 	HttpsCertFile string `json:"https-cert-file"` | 	HttpsCertFile string `json:"https-cert-file"` | ||||||
| 	HttpsKeyFile  string `json:"https-key-file"` | 	HttpsKeyFile  string `json:"https-key-file"` | ||||||
| @@ -92,6 +98,8 @@ var programConfig ProgramConfig = ProgramConfig{ | |||||||
| 	JobArchive:            "./var/job-archive", | 	JobArchive:            "./var/job-archive", | ||||||
| 	DisableArchive:        false, | 	DisableArchive:        false, | ||||||
| 	LdapConfig:            nil, | 	LdapConfig:            nil, | ||||||
|  | 	SessionMaxAge:         "168h", | ||||||
|  | 	JwtMaxAge:             "0", | ||||||
| 	HttpsCertFile:         "", | 	HttpsCertFile:         "", | ||||||
| 	HttpsKeyFile:          "", | 	HttpsKeyFile:          "", | ||||||
| 	UiDefaults: map[string]interface{}{ | 	UiDefaults: map[string]interface{}{ | ||||||
| @@ -250,6 +258,13 @@ func main() { | |||||||
|  |  | ||||||
| 	authentication := &auth.Authentication{} | 	authentication := &auth.Authentication{} | ||||||
| 	if !programConfig.DisableAuthentication { | 	if !programConfig.DisableAuthentication { | ||||||
|  | 		if d, err := time.ParseDuration(programConfig.SessionMaxAge); err != nil { | ||||||
|  | 			authentication.SessionMaxAge = d | ||||||
|  | 		} | ||||||
|  | 		if d, err := time.ParseDuration(programConfig.JwtMaxAge); err != nil { | ||||||
|  | 			authentication.JwtMaxAge = d | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if err := authentication.Init(db, programConfig.LdapConfig); err != nil { | 		if err := authentication.Init(db, programConfig.LdapConfig); err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user