mirror of
https://github.com/project-zot/zot.git
synced 2026-06-19 22:27:58 +08:00
fix: configure cookie Secure flag based on TLS configuration (#3482)
Make the Secure flag for session cookies configurable based on Zot's TLS settings. This allows cookies to work properly when Zot is accessed over HTTP (without TLS). Changes: - Add SecureSession field to AuthConfig to allow explicit control - Add UseSecureSession() method that returns true when TLS is configured, or uses SecureSession setting if provided - Update saveUserLoggedSession() to accept and use secure parameter - Add tests for UseSecureSession() in config_test.go - Enhance authn tests to verify cookie Secure flag behavior - Fix TestAuthnSessionErrors by creating new client without cookies The logic is: - If TLS is configured, cookies always have Secure=true - If TLS is not configured but SecureSession is explicitly set, use that value - Otherwise, default to Secure=false for HTTP-only deployments Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
This commit is contained in:
@@ -80,6 +80,7 @@ type AuthConfig struct {
|
||||
SessionHashKey []byte `json:"-"`
|
||||
SessionEncryptKey []byte `json:"-"`
|
||||
SessionDriver map[string]any `mapstructure:",omitempty"`
|
||||
SecureSession *bool `json:"secureSession,omitempty" mapstructure:"secureSession,omitempty"`
|
||||
}
|
||||
|
||||
// IsLdapAuthEnabled checks if LDAP authentication is enabled in this auth config.
|
||||
@@ -670,6 +671,7 @@ func (c *Config) UpdateReloadableConfig(newConfig *Config) {
|
||||
c.HTTP.Auth.LDAP = newConfig.HTTP.Auth.LDAP
|
||||
c.HTTP.Auth.APIKey = newConfig.HTTP.Auth.APIKey
|
||||
c.HTTP.Auth.OpenID = newConfig.HTTP.Auth.OpenID
|
||||
c.HTTP.Auth.SecureSession = newConfig.HTTP.Auth.SecureSession
|
||||
}
|
||||
|
||||
// Initialize and update AccessControlConfig
|
||||
@@ -1016,6 +1018,31 @@ func (c *Config) IsCompatEnabled() bool {
|
||||
return len(c.HTTP.Compat) > 0
|
||||
}
|
||||
|
||||
// UseSecureSession returns whether cookies should have the Secure flag set.
|
||||
// If TLS is configured, always returns true. Otherwise, returns the value
|
||||
// of SecureSession if set, or false by default.
|
||||
func (c *Config) UseSecureSession() bool {
|
||||
if c == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
|
||||
// If TLS is configured, cookies should be secure
|
||||
if c.HTTP.TLS != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
// If TLS is not configured, check if SecureSession is explicitly set in auth config
|
||||
if c.HTTP.Auth != nil && c.HTTP.Auth.SecureSession != nil {
|
||||
return *c.HTTP.Auth.SecureSession
|
||||
}
|
||||
|
||||
// Default to false if TLS is not configured and no explicit setting
|
||||
return false
|
||||
}
|
||||
|
||||
// IsOpenIDSupported checks if the provider supports OpenID.
|
||||
func IsOpenIDSupported(provider string) bool {
|
||||
for _, supportedProvider := range openIDSupportedProviders {
|
||||
|
||||
@@ -1989,6 +1989,83 @@ func TestConfig(t *testing.T) {
|
||||
So(cfg.IsMTLSAuthEnabled(), ShouldBeTrue) // No basic auth, so mTLS enabled
|
||||
})
|
||||
|
||||
Convey("Test UseSecureSession()", func() {
|
||||
// Test with nil Config
|
||||
var cfg *config.Config = nil
|
||||
|
||||
So(cfg.UseSecureSession(), ShouldBeFalse)
|
||||
|
||||
// Test with Config but no TLS and no Auth
|
||||
cfg = &config.Config{
|
||||
HTTP: config.HTTPConfig{
|
||||
TLS: nil,
|
||||
Auth: nil,
|
||||
},
|
||||
}
|
||||
So(cfg.UseSecureSession(), ShouldBeFalse)
|
||||
|
||||
// Test with TLS configured (should return true)
|
||||
cfg = &config.Config{
|
||||
HTTP: config.HTTPConfig{
|
||||
TLS: &config.TLSConfig{
|
||||
Cert: "/path/to/cert.pem",
|
||||
Key: "/path/to/key.pem",
|
||||
},
|
||||
},
|
||||
}
|
||||
So(cfg.UseSecureSession(), ShouldBeTrue)
|
||||
|
||||
// Test with no TLS but SecureSession explicitly set to true
|
||||
secureTrue := true
|
||||
cfg = &config.Config{
|
||||
HTTP: config.HTTPConfig{
|
||||
TLS: nil,
|
||||
Auth: &config.AuthConfig{
|
||||
SecureSession: &secureTrue,
|
||||
},
|
||||
},
|
||||
}
|
||||
So(cfg.UseSecureSession(), ShouldBeTrue)
|
||||
|
||||
// Test with no TLS but SecureSession explicitly set to false
|
||||
secureFalse := false
|
||||
cfg = &config.Config{
|
||||
HTTP: config.HTTPConfig{
|
||||
TLS: nil,
|
||||
Auth: &config.AuthConfig{
|
||||
SecureSession: &secureFalse,
|
||||
},
|
||||
},
|
||||
}
|
||||
So(cfg.UseSecureSession(), ShouldBeFalse)
|
||||
|
||||
// Test with no TLS and Auth but SecureSession not set
|
||||
cfg = &config.Config{
|
||||
HTTP: config.HTTPConfig{
|
||||
TLS: nil,
|
||||
Auth: &config.AuthConfig{
|
||||
APIKey: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
So(cfg.UseSecureSession(), ShouldBeFalse)
|
||||
|
||||
// Test with TLS configured and SecureSession set (TLS should take precedence)
|
||||
secureTrue = true
|
||||
cfg = &config.Config{
|
||||
HTTP: config.HTTPConfig{
|
||||
TLS: &config.TLSConfig{
|
||||
Cert: "/path/to/cert.pem",
|
||||
Key: "/path/to/key.pem",
|
||||
},
|
||||
Auth: &config.AuthConfig{
|
||||
SecureSession: &secureTrue,
|
||||
},
|
||||
},
|
||||
}
|
||||
So(cfg.UseSecureSession(), ShouldBeTrue) // TLS takes precedence
|
||||
})
|
||||
|
||||
Convey("Test IsCompatEnabled()", func() {
|
||||
// Test with nil Config
|
||||
var cfg *config.Config = nil
|
||||
|
||||
Reference in New Issue
Block a user