mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-17 04:37:48 +00:00
review fixes apr 2026 (#130)
* Multiple fixes - refresh coordinator dedup + memory pressure wire - middleware sse consolidation + timer leak + claim cache - universal cache sync backfill + isDebug gate - lazy background task race - memory monitor stw cached + refresh() api * fix(auth): suppress OIDC redirects on non-navigation requests - [x] Add isNonNavigationRequest using Sec-Fetch-Mode and Accept headers - [x] Add comprehensive TestIsNonNavigationRequest - [x] Update ServeHTTP to 401 non-navigation and AJAX requests Fixes #129 * feat(config): add custom CA and insecure skip verify for OIDC TLS - [x] Add CACertPath, CACertPEM, InsecureSkipVerify to Config - [x] Implement loadCACertPool for CA bundle loading - [x] Update HTTPClientConfig with RootCAs and InsecureSkipVerify - [x] Apply CA pool and skip verify to pooled HTTP clients - [x] Enhance configKey to distinguish TLS configs - [x] Add comprehensive ca_cert_test.go Fixes #125 * feat(oidc): add custom CA certificate support for private OIDC providers - [x] Add caCertPath, caCertPEM, insecureSkipVerify config options - [x] Update traefik.yml with new OIDC client config fields - [x] Add configuration schema descriptions for new options - [x] Update README table and add Custom CA Certificates section * Fix the documentation. * test(redis): add oversized argument rejection test - [x] Add TestRedisConn_RejectOversizedArgumentBytes - [x] Import strings package * Dependencies cleanup
This commit is contained in:
+53
@@ -1216,6 +1216,18 @@ type SessionData struct {
|
||||
dirty bool
|
||||
|
||||
inUse bool
|
||||
|
||||
// cachedClaimsToken is the ID token string whose claims were last parsed and
|
||||
// cached. A lazy, per-request cache to avoid re-parsing the JWT on every
|
||||
// authenticated request (e.g. for headerTemplates). Protected by sessionMutex.
|
||||
cachedClaimsToken string
|
||||
|
||||
// cachedClaims holds the parsed claims for cachedClaimsToken.
|
||||
cachedClaims map[string]interface{}
|
||||
|
||||
// cachedClaimsErr holds the parse error (if any) for cachedClaimsToken so
|
||||
// failures are not retried within the same request.
|
||||
cachedClaimsErr error
|
||||
}
|
||||
|
||||
// IsDirty returns true if the session data has been modified since it was last loaded or saved.
|
||||
@@ -1737,6 +1749,12 @@ func (sd *SessionData) Reset() {
|
||||
sd.request = nil
|
||||
sd.useCombinedStorage = true // Reset to use combined storage by default
|
||||
|
||||
// Drop any cached claims so pooled SessionData does not leak claim data
|
||||
// between requests/users.
|
||||
sd.cachedClaimsToken = ""
|
||||
sd.cachedClaims = nil
|
||||
sd.cachedClaimsErr = nil
|
||||
|
||||
// Reset the refresh mutex to ensure clean state
|
||||
// Note: We don't need to lock it since sessionMutex is already held
|
||||
// and this session is not in use by any request
|
||||
@@ -2514,6 +2532,41 @@ func (sd *SessionData) GetIDToken() string {
|
||||
return sd.getIDTokenUnsafe()
|
||||
}
|
||||
|
||||
// GetIDTokenClaims returns claims parsed from the current ID token, caching
|
||||
// the result on the SessionData so repeated callers within the same request
|
||||
// do not re-parse the JWT. The cache is keyed on the ID token string and is
|
||||
// cleared when the SessionData is reset (see Reset) or when the ID token
|
||||
// changes (e.g. after a refresh).
|
||||
//
|
||||
// The parser parameter is typically the TraefikOidc.extractClaimsFunc, which
|
||||
// lets tests inject mocks just like the direct call it replaces.
|
||||
//
|
||||
// Returns an empty claims map and a nil error when the session has no ID
|
||||
// token, matching the existing "no-op" behavior of the caller sites.
|
||||
func (sd *SessionData) GetIDTokenClaims(parser func(string) (map[string]interface{}, error)) (map[string]interface{}, error) {
|
||||
sd.sessionMutex.Lock()
|
||||
defer sd.sessionMutex.Unlock()
|
||||
|
||||
token := sd.getIDTokenUnsafe()
|
||||
if token == "" {
|
||||
// Invalidate any stale cache without running the parser.
|
||||
sd.cachedClaimsToken = ""
|
||||
sd.cachedClaims = nil
|
||||
sd.cachedClaimsErr = nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if sd.cachedClaimsToken == token && (sd.cachedClaims != nil || sd.cachedClaimsErr != nil) {
|
||||
return sd.cachedClaims, sd.cachedClaimsErr
|
||||
}
|
||||
|
||||
claims, err := parser(token)
|
||||
sd.cachedClaimsToken = token
|
||||
sd.cachedClaims = claims
|
||||
sd.cachedClaimsErr = err
|
||||
return claims, err
|
||||
}
|
||||
|
||||
// getIDTokenUnsafe retrieves the ID token without acquiring locks.
|
||||
// Enhanced ID token retrieval with comprehensive integrity checks and chunking support.
|
||||
// Used when the session mutex is already held to prevent deadlocks.
|
||||
|
||||
Reference in New Issue
Block a user