Make userinfo cache configurable

This commit is contained in:
Benedikt Kulmann
2020-11-18 11:14:29 +01:00
parent f2c653aeec
commit a410d40166
5 changed files with 55 additions and 26 deletions

View File

@@ -281,8 +281,8 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
}),
middleware.HTTPClient(oidcHTTPClient),
middleware.OIDCIss(cfg.OIDC.Issuer),
middleware.TokenCacheSize(1024),
middleware.TokenCacheTTL(time.Second*10),
middleware.TokenCacheSize(cfg.OIDC.UserinfoCache.Size),
middleware.TokenCacheTTL(time.Second*time.Duration(cfg.OIDC.UserinfoCache.TTL)),
),
middleware.BasicAuth(
middleware.Logger(l),

View File

@@ -83,6 +83,12 @@ type Reva struct {
Address string
}
// Cache is a TTL cache configuration.
type Cache struct {
Size int
TTL int
}
// Config combines all available configuration parts.
type Config struct {
File string
@@ -105,8 +111,9 @@ type Config struct {
// OIDC is the config for the OpenID-Connect middleware. If set the proxy will try to authenticate every request
// with the configured oidc-provider
type OIDC struct {
Issuer string
Insecure bool
Issuer string
Insecure bool
UserinfoCache Cache
}
// PolicySelector is the toplevel-configuration for different selectors

View File

@@ -202,6 +202,20 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
EnvVars: []string{"PROXY_OIDC_INSECURE"},
Destination: &cfg.OIDC.Insecure,
},
&cli.IntFlag{
Name: "oidc-userinfo-cache-tll",
Value: 10,
Usage: "Fallback TTL in seconds for caching userinfo, when no token lifetime can be identified",
EnvVars: []string{"PROXY_OIDC_USERINFO_CACHE_TTL"},
Destination: &cfg.OIDC.UserinfoCache.TTL,
},
&cli.IntFlag{
Name: "oidc-userinfo-cache-size",
Value: 1024,
Usage: "Max entries for caching userinfo",
EnvVars: []string{"PROXY_OIDC_USERINFO_CACHE_SIZE"},
Destination: &cfg.OIDC.UserinfoCache.Size,
},
&cli.BoolFlag{
Name: "autoprovision-accounts",

View File

@@ -21,8 +21,8 @@ type OIDCProvider interface {
func OIDCAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
options := newOptions(optionSetters...)
tokenCache := cache.NewCache(
cache.Size(options.TokenCacheSize),
cache.TTL(options.TokenCacheTTL),
cache.Size(options.UserinfoCacheSize),
cache.TTL(options.UserinfoCacheTTL),
)
return func(next http.Handler) http.Handler {
@@ -54,20 +54,9 @@ func (m oidcAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
if m.provider == nil {
// Lazily initialize a provider
// provider needs to be cached as when it is created
// it will fetch the keys from the issuer using the .well-known
// endpoint
provider, err := m.providerFunc()
if err != nil {
m.logger.Error().Err(err).Msg("could not initialize oidcAuth provider")
w.WriteHeader(http.StatusInternalServerError)
return
}
m.provider = provider
if m.getProvider() == nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
@@ -136,6 +125,7 @@ func (m oidcAuth) shouldServe(req *http.Request) bool {
}
// todo: looks dirty, check later
// TODO: make a PR to coreos/go-oidc for exposing userinfo endpoint on provider, see https://github.com/coreos/go-oidc/issues/248
for _, ignoringPath := range []string{"/konnect/v1/userinfo"} {
if req.URL.Path == ignoringPath {
return false
@@ -144,3 +134,21 @@ func (m oidcAuth) shouldServe(req *http.Request) bool {
return strings.HasPrefix(header, "Bearer ")
}
func (m oidcAuth) getProvider() OIDCProvider {
if m.provider == nil {
// Lazily initialize a provider
// provider needs to be cached as when it is created
// it will fetch the keys from the issuer using the .well-known
// endpoint
provider, err := m.providerFunc()
if err != nil {
m.logger.Error().Err(err).Msg("could not initialize oidcAuth provider")
return nil
}
m.provider = provider
}
return m.provider
}

View File

@@ -42,10 +42,10 @@ type Options struct {
AutoprovisionAccounts bool
// EnableBasicAuth to allow basic auth
EnableBasicAuth bool
// TokenCacheSize defines the max number of entries in the token cache, intended for the oidc_auth middleware
TokenCacheSize int
// TokenCacheTTL sets the max cache duration for the token cache, intended for the oidc_auth middleware
TokenCacheTTL time.Duration
// UserinfoCacheSize defines the max number of entries in the userinfo cache, intended for the oidc_auth middleware
UserinfoCacheSize int
// UserinfoCacheTTL sets the max cache duration for the userinfo cache, intended for the oidc_auth middleware
UserinfoCacheTTL time.Duration
}
// newOptions initializes the available default options.
@@ -146,13 +146,13 @@ func EnableBasicAuth(enableBasicAuth bool) Option {
// TokenCacheSize provides a function to set the TokenCacheSize
func TokenCacheSize(size int) Option {
return func(o *Options) {
o.TokenCacheSize = size
o.UserinfoCacheSize = size
}
}
// TokenCacheTTL provides a function to set the TokenCacheTTL
func TokenCacheTTL(ttl time.Duration) Option {
return func(o *Options) {
o.TokenCacheTTL = ttl
o.UserinfoCacheTTL = ttl
}
}