Improve cookie setting.

This commit is contained in:
2024-12-06 23:43:47 +00:00
parent a6fa4d8789
commit 01ee7c4dc8
4 changed files with 23 additions and 21 deletions
+12 -2
View File
@@ -17,6 +17,16 @@ import (
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
) )
func newSessionOptions(isSecure bool) *sessions.Options {
return &sessions.Options{
HttpOnly: true,
Secure: isSecure,
SameSite: http.SameSiteLaxMode,
MaxAge: ConstSessionTimeout,
Path: "/",
}
}
// generateNonce generates a random nonce // generateNonce generates a random nonce
func generateNonce() (string, error) { func generateNonce() (string, error) {
nonceBytes := make([]byte, 32) nonceBytes := make([]byte, 32)
@@ -101,7 +111,7 @@ func (t *TraefikOidc) handleExpiredToken(rw http.ResponseWriter, req *http.Reque
session.Values["csrf"] = uuid.New().String() session.Values["csrf"] = uuid.New().String()
session.Values["incoming_path"] = req.URL.Path session.Values["incoming_path"] = req.URL.Path
session.Values["nonce"], _ = generateNonce() session.Values["nonce"], _ = generateNonce()
session.Options = defaultSessionOptions session.Options = newSessionOptions(t.determineScheme(req) == "https")
// Save the session before initiating authentication // Save the session before initiating authentication
if err := session.Save(req, rw); err != nil { if err := session.Save(req, rw); err != nil {
@@ -222,7 +232,7 @@ func (t *TraefikOidc) handleCallback(rw http.ResponseWriter, req *http.Request,
session.Values["email"] = email session.Values["email"] = email
session.Values["id_token"] = idToken session.Values["id_token"] = idToken
session.Values["refresh_token"] = tokenResponse.RefreshToken session.Values["refresh_token"] = tokenResponse.RefreshToken
session.Options = defaultSessionOptions session.Options = newSessionOptions(t.determineScheme(req) == "https")
// Remove CSRF and nonce from session // Remove CSRF and nonce from session
delete(session.Values, "csrf") delete(session.Values, "csrf")
+9 -9
View File
@@ -186,7 +186,9 @@ func (t *TraefikOidc) VerifyJWTSignatureAndClaims(jwt *JWT, token string) error
// New creates a new instance of the OIDC middleware // New creates a new instance of the OIDC middleware
func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) { func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
store := sessions.NewCookieStore([]byte(config.SessionEncryptionKey)) store := sessions.NewCookieStore([]byte(config.SessionEncryptionKey))
store.Options = defaultSessionOptions store.Options = newSessionOptions(func() bool {
return config.ForceHTTPS
}())
// Setup HTTP client // Setup HTTP client
transport := &http.Transport{ transport := &http.Transport{
@@ -200,7 +202,7 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
}, },
ForceAttemptHTTP2: true, ForceAttemptHTTP2: true,
TLSHandshakeTimeout: 10 * time.Second, TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second, ExpectContinueTimeout: 0,
MaxIdleConns: 100, MaxIdleConns: 100,
MaxIdleConnsPerHost: 100, MaxIdleConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second, IdleConnTimeout: 90 * time.Second,
@@ -377,12 +379,9 @@ func (t *TraefikOidc) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
} }
// Determine the scheme (http/https) and host // Determine the scheme (http/https) and host
t.scheme = t.determineScheme(req) scheme := t.determineScheme(req)
defaultSessionOptions.Secure = t.scheme == "https"
host := t.determineHost(req) host := t.determineHost(req)
redirectURL := buildFullURL(scheme, host, t.redirURLPath)
redirectURL := buildFullURL(t.scheme, host, t.redirURLPath)
// Build the redirect URL if not already set // Build the redirect URL if not already set
if redirectURL == "" { if redirectURL == "" {
redirectURL = buildFullURL(t.scheme, host, t.redirURLPath) redirectURL = buildFullURL(t.scheme, host, t.redirURLPath)
@@ -397,6 +396,7 @@ func (t *TraefikOidc) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
return return
} }
session.Options = newSessionOptions(scheme == "https")
t.logger.Debugf("Session contents at start: %+v", session.Values) t.logger.Debugf("Session contents at start: %+v", session.Values)
// Handle logout URL // Handle logout URL
@@ -584,7 +584,7 @@ func (t *TraefikOidc) defaultInitiateAuthentication(rw http.ResponseWriter, req
csrfToken := uuid.New().String() csrfToken := uuid.New().String()
session.Values["csrf"] = csrfToken session.Values["csrf"] = csrfToken
session.Values["incoming_path"] = req.URL.Path session.Values["incoming_path"] = req.URL.Path
session.Options = defaultSessionOptions session.Options = newSessionOptions(t.determineScheme(req) == "https")
t.logger.Debugf("Setting CSRF token: %s", csrfToken) t.logger.Debugf("Setting CSRF token: %s", csrfToken)
// Generate nonce // Generate nonce
@@ -710,7 +710,7 @@ func (t *TraefikOidc) refreshToken(rw http.ResponseWriter, req *http.Request, se
// Update session with new tokens // Update session with new tokens
session.Values["id_token"] = newToken.IDToken session.Values["id_token"] = newToken.IDToken
session.Values["refresh_token"] = newToken.RefreshToken session.Values["refresh_token"] = newToken.RefreshToken
session.Options = defaultSessionOptions session.Options = newSessionOptions(t.determineScheme(req) == "https")
if err := session.Save(req, rw); err != nil { if err := session.Save(req, rw); err != nil {
t.logger.Errorf("Failed to save refreshed session: %v", err) t.logger.Errorf("Failed to save refreshed session: %v", err)
return false return false
+2
View File
@@ -1223,6 +1223,8 @@ func TestHandleExpiredToken(t *testing.T) {
t.Error("Nonce not set") t.Error("Nonce not set")
} }
defaultSessionOptions := newSessionOptions(tOidc.determineScheme(req) == "https")
// Verify session options // Verify session options
if session.Options.MaxAge != defaultSessionOptions.MaxAge { if session.Options.MaxAge != defaultSessionOptions.MaxAge {
t.Error("Session MaxAge not set correctly") t.Error("Session MaxAge not set correctly")
-10
View File
@@ -6,8 +6,6 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"github.com/gorilla/sessions"
) )
const ( const (
@@ -35,14 +33,6 @@ type Config struct {
HTTPClient *http.Client HTTPClient *http.Client
} }
var defaultSessionOptions = &sessions.Options{
HttpOnly: true,
Secure: false,
SameSite: http.SameSiteLaxMode,
MaxAge: ConstSessionTimeout,
Path: "/",
}
// CreateConfig creates a new Config with default values // CreateConfig creates a new Config with default values
func CreateConfig() *Config { func CreateConfig() *Config {
c := &Config{} c := &Config{}