mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-09-06 16:17:08 +00:00
Save an http.Client with each upstreamoidc.ProviderConfig object.
This allows the token exchange request to be performed with the correct TLS configuration. We go to a bit of extra work to make sure the `http.Client` object is cached between reconcile operations so that connection pooling works as expected. Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
@@ -70,15 +70,21 @@ type IDPCache interface {
|
||||
// lruValidatorCache caches the *oidc.Provider associated with a particular issuer/TLS configuration.
|
||||
type lruValidatorCache struct{ cache *cache.Expiring }
|
||||
|
||||
func (c *lruValidatorCache) getProvider(spec *v1alpha1.UpstreamOIDCProviderSpec) *oidc.Provider {
|
||||
if result, ok := c.cache.Get(c.cacheKey(spec)); ok {
|
||||
return result.(*oidc.Provider)
|
||||
}
|
||||
return nil
|
||||
type lruValidatorCacheEntry struct {
|
||||
provider *oidc.Provider
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func (c *lruValidatorCache) putProvider(spec *v1alpha1.UpstreamOIDCProviderSpec, provider *oidc.Provider) {
|
||||
c.cache.Set(c.cacheKey(spec), provider, validatorCacheTTL)
|
||||
func (c *lruValidatorCache) getProvider(spec *v1alpha1.UpstreamOIDCProviderSpec) (*oidc.Provider, *http.Client) {
|
||||
if result, ok := c.cache.Get(c.cacheKey(spec)); ok {
|
||||
entry := result.(*lruValidatorCacheEntry)
|
||||
return entry.provider, entry.client
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *lruValidatorCache) putProvider(spec *v1alpha1.UpstreamOIDCProviderSpec, provider *oidc.Provider, client *http.Client) {
|
||||
c.cache.Set(c.cacheKey(spec), &lruValidatorCacheEntry{provider: provider, client: client}, validatorCacheTTL)
|
||||
}
|
||||
|
||||
func (c *lruValidatorCache) cacheKey(spec *v1alpha1.UpstreamOIDCProviderSpec) interface{} {
|
||||
@@ -97,8 +103,8 @@ type controller struct {
|
||||
providers idpinformers.UpstreamOIDCProviderInformer
|
||||
secrets corev1informers.SecretInformer
|
||||
validatorCache interface {
|
||||
getProvider(spec *v1alpha1.UpstreamOIDCProviderSpec) *oidc.Provider
|
||||
putProvider(spec *v1alpha1.UpstreamOIDCProviderSpec, provider *oidc.Provider)
|
||||
getProvider(*v1alpha1.UpstreamOIDCProviderSpec) (*oidc.Provider, *http.Client)
|
||||
putProvider(*v1alpha1.UpstreamOIDCProviderSpec, *oidc.Provider, *http.Client)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +230,7 @@ func (c *controller) validateSecret(upstream *v1alpha1.UpstreamOIDCProvider, res
|
||||
|
||||
// If everything is valid, update the result and set the condition to true.
|
||||
result.Config.ClientID = string(clientID)
|
||||
result.Config.ClientSecret = string(clientSecret)
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeClientCredsValid,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
@@ -234,8 +241,8 @@ func (c *controller) validateSecret(upstream *v1alpha1.UpstreamOIDCProvider, res
|
||||
|
||||
// validateIssuer validates the .spec.issuer field, performs OIDC discovery, and returns the appropriate OIDCDiscoverySucceeded condition.
|
||||
func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.UpstreamOIDCProvider, result *upstreamoidc.ProviderConfig) *v1alpha1.Condition {
|
||||
// Get the provider (from cache if possible).
|
||||
discoveredProvider := c.validatorCache.getProvider(&upstream.Spec)
|
||||
// Get the provider and HTTP Client from cache if possible.
|
||||
discoveredProvider, httpClient := c.validatorCache.getProvider(&upstream.Spec)
|
||||
|
||||
// If the provider does not exist in the cache, do a fresh discovery lookup and save to the cache.
|
||||
if discoveredProvider == nil {
|
||||
@@ -248,7 +255,7 @@ func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.Upst
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
httpClient := &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}
|
||||
httpClient = &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}
|
||||
|
||||
discoveredProvider, err = oidc.NewProvider(oidc.ClientContext(ctx, httpClient), upstream.Spec.Issuer)
|
||||
if err != nil {
|
||||
@@ -261,7 +268,7 @@ func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.Upst
|
||||
}
|
||||
|
||||
// Update the cache with the newly discovered value.
|
||||
c.validatorCache.putProvider(&upstream.Spec, discoveredProvider)
|
||||
c.validatorCache.putProvider(&upstream.Spec, discoveredProvider, httpClient)
|
||||
}
|
||||
|
||||
// Parse out and validate the discovered authorize endpoint.
|
||||
@@ -286,6 +293,7 @@ func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.Upst
|
||||
// If everything is valid, update the result and set the condition to true.
|
||||
result.Config.Endpoint = discoveredProvider.Endpoint()
|
||||
result.Provider = discoveredProvider
|
||||
result.Client = httpClient
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeOIDCDiscoverySucceeded,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
|
||||
Reference in New Issue
Block a user