mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
feat: add cookiePath config to scope session cookies to subpath
Fixes #122.
This commit is contained in:
@@ -121,6 +121,7 @@ Full reference in [docs/CONFIGURATION.md](docs/CONFIGURATION.md).
|
||||
| `enablePKCE` | `false` | PKCE on the auth code flow. |
|
||||
| `cookieDomain` | auto | Set explicitly for multi-subdomain setups (`.example.com`). |
|
||||
| `cookiePrefix` | `_oidc_raczylo_` | Unique prefix per middleware instance to isolate sessions. |
|
||||
| `cookiePath` | `/` | Restrict cookies to a path prefix. Set to the middleware's path (e.g. `/app`) to prevent the browser from sending OIDC cookies to unprotected paths, avoiding 431 "Request Header Or Cookie Too Large" errors on mixed-use domains. |
|
||||
| `sessionMaxAge` | `86400` | Session lifetime in seconds. |
|
||||
| `refreshGracePeriodSeconds` | `60` | Proactively refresh tokens this many seconds before expiry. |
|
||||
| `maxRefreshTokenAgeSeconds` | `21600` | Heuristic max stored refresh-token lifetime (6h). Past this, the plugin treats the RT as expired without contacting the IdP — returns 401 to AJAX, full re-auth on navigations. Set `0` to disable. Tune to match your IdP's RT TTL. |
|
||||
|
||||
@@ -335,6 +335,10 @@ func NewWithContext(ctx context.Context, config *Config, next http.Handler, name
|
||||
// Convert sessionMaxAge from seconds to duration (0 will use default 24 hours)
|
||||
sessionMaxAge := time.Duration(config.SessionMaxAge) * time.Second
|
||||
t.sessionManager, _ = NewSessionManager(config.SessionEncryptionKey, config.ForceHTTPS, config.CookieDomain, config.CookiePrefix, sessionMaxAge, t.logger) // Safe to ignore: session manager creation with fallback to defaults
|
||||
if config.CookiePath != "" {
|
||||
t.sessionManager.cookiePath = config.CookiePath
|
||||
t.logger.Debugf("Using configured cookie path: %s", config.CookiePath)
|
||||
}
|
||||
t.errorRecoveryManager = NewErrorRecoveryManager(t.logger)
|
||||
|
||||
// Initialize token resilience manager with default configuration
|
||||
|
||||
+7
-1
@@ -382,6 +382,7 @@ type SessionManager struct {
|
||||
cancel context.CancelFunc
|
||||
cookieDomain string
|
||||
cookiePrefix string
|
||||
cookiePath string
|
||||
sessionMaxAge time.Duration
|
||||
activeSessions int64
|
||||
poolHits int64
|
||||
@@ -851,7 +852,12 @@ func (sm *SessionManager) EnhanceSessionSecurity(options *sessions.Options, r *h
|
||||
}
|
||||
|
||||
options.HttpOnly = true
|
||||
options.Path = "/" // Ensure cookies are available on all paths for OAuth flow
|
||||
// Use configured cookie path (default "/" for backward compatibility)
|
||||
cookiePath := sm.cookiePath
|
||||
if cookiePath == "" {
|
||||
cookiePath = "/"
|
||||
}
|
||||
options.Path = cookiePath
|
||||
|
||||
if sm.cookieDomain != "" {
|
||||
options.Domain = sm.cookieDomain
|
||||
|
||||
+24
-17
@@ -64,23 +64,30 @@ type Config struct {
|
||||
// IdPs do not expose RT TTL on the wire, so this is intentionally a
|
||||
// conservative heuristic; tune to match your provider configuration.
|
||||
// Default 21600 (6h). Set to 0 to disable the check.
|
||||
MaxRefreshTokenAgeSeconds int `json:"maxRefreshTokenAgeSeconds"`
|
||||
SessionMaxAge int `json:"sessionMaxAge"`
|
||||
RateLimit int `json:"rateLimit"`
|
||||
OverrideScopes bool `json:"overrideScopes"`
|
||||
DisableReplayDetection bool `json:"disableReplayDetection,omitempty"`
|
||||
RequireTokenIntrospection bool `json:"requireTokenIntrospection,omitempty"`
|
||||
AllowOpaqueTokens bool `json:"allowOpaqueTokens,omitempty"`
|
||||
StrictAudienceValidation bool `json:"strictAudienceValidation,omitempty"`
|
||||
EnablePKCE bool `json:"enablePKCE"`
|
||||
ForceHTTPS bool `json:"forceHTTPS"`
|
||||
AllowPrivateIPAddresses bool `json:"allowPrivateIPAddresses,omitempty"`
|
||||
MinimalHeaders bool `json:"minimalHeaders,omitempty"`
|
||||
StripAuthCookies bool `json:"stripAuthCookies,omitempty"`
|
||||
EnableBackchannelLogout bool `json:"enableBackchannelLogout,omitempty"`
|
||||
EnableFrontchannelLogout bool `json:"enableFrontchannelLogout,omitempty"`
|
||||
BackchannelLogoutURL string `json:"backchannelLogoutURL,omitempty"`
|
||||
FrontchannelLogoutURL string `json:"frontchannelLogoutURL,omitempty"`
|
||||
MaxRefreshTokenAgeSeconds int `json:"maxRefreshTokenAgeSeconds"`
|
||||
SessionMaxAge int `json:"sessionMaxAge"`
|
||||
RateLimit int `json:"rateLimit"`
|
||||
OverrideScopes bool `json:"overrideScopes"`
|
||||
DisableReplayDetection bool `json:"disableReplayDetection,omitempty"`
|
||||
RequireTokenIntrospection bool `json:"requireTokenIntrospection,omitempty"`
|
||||
AllowOpaqueTokens bool `json:"allowOpaqueTokens,omitempty"`
|
||||
StrictAudienceValidation bool `json:"strictAudienceValidation,omitempty"`
|
||||
EnablePKCE bool `json:"enablePKCE"`
|
||||
ForceHTTPS bool `json:"forceHTTPS"`
|
||||
AllowPrivateIPAddresses bool `json:"allowPrivateIPAddresses,omitempty"`
|
||||
MinimalHeaders bool `json:"minimalHeaders,omitempty"`
|
||||
StripAuthCookies bool `json:"stripAuthCookies,omitempty"`
|
||||
// CookiePath restricts session cookies to a specific path prefix instead of "/".
|
||||
// When traefikoidc protects some but not all paths on a domain, set this to the
|
||||
// middleware's path prefix (e.g. "/app-protegido") so the browser does not send
|
||||
// the OIDC session cookies to unprotected paths — preventing "Request Header
|
||||
// Or Cookie Too Large" (431) errors on those paths.
|
||||
// Default "/" (all paths, current behaviour).
|
||||
CookiePath string `json:"cookiePath,omitempty"`
|
||||
EnableBackchannelLogout bool `json:"enableBackchannelLogout,omitempty"`
|
||||
EnableFrontchannelLogout bool `json:"enableFrontchannelLogout,omitempty"`
|
||||
BackchannelLogoutURL string `json:"backchannelLogoutURL,omitempty"`
|
||||
FrontchannelLogoutURL string `json:"frontchannelLogoutURL,omitempty"`
|
||||
// CACertPath is an optional filesystem path to a PEM-encoded CA bundle used
|
||||
// to verify the OIDC provider's TLS certificate. Use this when the provider
|
||||
// is signed by an internal/private CA that is not in the system trust store.
|
||||
|
||||
Reference in New Issue
Block a user