Make userinfo cache configurable
This commit is contained in:
@@ -281,8 +281,8 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
|
|||||||
}),
|
}),
|
||||||
middleware.HTTPClient(oidcHTTPClient),
|
middleware.HTTPClient(oidcHTTPClient),
|
||||||
middleware.OIDCIss(cfg.OIDC.Issuer),
|
middleware.OIDCIss(cfg.OIDC.Issuer),
|
||||||
middleware.TokenCacheSize(1024),
|
middleware.TokenCacheSize(cfg.OIDC.UserinfoCache.Size),
|
||||||
middleware.TokenCacheTTL(time.Second*10),
|
middleware.TokenCacheTTL(time.Second*time.Duration(cfg.OIDC.UserinfoCache.TTL)),
|
||||||
),
|
),
|
||||||
middleware.BasicAuth(
|
middleware.BasicAuth(
|
||||||
middleware.Logger(l),
|
middleware.Logger(l),
|
||||||
|
|||||||
@@ -83,6 +83,12 @@ type Reva struct {
|
|||||||
Address string
|
Address string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache is a TTL cache configuration.
|
||||||
|
type Cache struct {
|
||||||
|
Size int
|
||||||
|
TTL int
|
||||||
|
}
|
||||||
|
|
||||||
// Config combines all available configuration parts.
|
// Config combines all available configuration parts.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
File string
|
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
|
// OIDC is the config for the OpenID-Connect middleware. If set the proxy will try to authenticate every request
|
||||||
// with the configured oidc-provider
|
// with the configured oidc-provider
|
||||||
type OIDC struct {
|
type OIDC struct {
|
||||||
Issuer string
|
Issuer string
|
||||||
Insecure bool
|
Insecure bool
|
||||||
|
UserinfoCache Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
// PolicySelector is the toplevel-configuration for different selectors
|
// PolicySelector is the toplevel-configuration for different selectors
|
||||||
|
|||||||
@@ -202,6 +202,20 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
|||||||
EnvVars: []string{"PROXY_OIDC_INSECURE"},
|
EnvVars: []string{"PROXY_OIDC_INSECURE"},
|
||||||
Destination: &cfg.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{
|
&cli.BoolFlag{
|
||||||
Name: "autoprovision-accounts",
|
Name: "autoprovision-accounts",
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ type OIDCProvider interface {
|
|||||||
func OIDCAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
|
func OIDCAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
|
||||||
options := newOptions(optionSetters...)
|
options := newOptions(optionSetters...)
|
||||||
tokenCache := cache.NewCache(
|
tokenCache := cache.NewCache(
|
||||||
cache.Size(options.TokenCacheSize),
|
cache.Size(options.UserinfoCacheSize),
|
||||||
cache.TTL(options.TokenCacheTTL),
|
cache.TTL(options.UserinfoCacheTTL),
|
||||||
)
|
)
|
||||||
|
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
@@ -54,20 +54,9 @@ func (m oidcAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.provider == nil {
|
if m.getProvider() == nil {
|
||||||
// Lazily initialize a provider
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
|
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: 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"} {
|
for _, ignoringPath := range []string{"/konnect/v1/userinfo"} {
|
||||||
if req.URL.Path == ignoringPath {
|
if req.URL.Path == ignoringPath {
|
||||||
return false
|
return false
|
||||||
@@ -144,3 +134,21 @@ func (m oidcAuth) shouldServe(req *http.Request) bool {
|
|||||||
|
|
||||||
return strings.HasPrefix(header, "Bearer ")
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ type Options struct {
|
|||||||
AutoprovisionAccounts bool
|
AutoprovisionAccounts bool
|
||||||
// EnableBasicAuth to allow basic auth
|
// EnableBasicAuth to allow basic auth
|
||||||
EnableBasicAuth bool
|
EnableBasicAuth bool
|
||||||
// TokenCacheSize defines the max number of entries in the token cache, intended for the oidc_auth middleware
|
// UserinfoCacheSize defines the max number of entries in the userinfo cache, intended for the oidc_auth middleware
|
||||||
TokenCacheSize int
|
UserinfoCacheSize int
|
||||||
// TokenCacheTTL sets the max cache duration for the token cache, intended for the oidc_auth middleware
|
// UserinfoCacheTTL sets the max cache duration for the userinfo cache, intended for the oidc_auth middleware
|
||||||
TokenCacheTTL time.Duration
|
UserinfoCacheTTL time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// newOptions initializes the available default options.
|
// newOptions initializes the available default options.
|
||||||
@@ -146,13 +146,13 @@ func EnableBasicAuth(enableBasicAuth bool) Option {
|
|||||||
// TokenCacheSize provides a function to set the TokenCacheSize
|
// TokenCacheSize provides a function to set the TokenCacheSize
|
||||||
func TokenCacheSize(size int) Option {
|
func TokenCacheSize(size int) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.TokenCacheSize = size
|
o.UserinfoCacheSize = size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenCacheTTL provides a function to set the TokenCacheTTL
|
// TokenCacheTTL provides a function to set the TokenCacheTTL
|
||||||
func TokenCacheTTL(ttl time.Duration) Option {
|
func TokenCacheTTL(ttl time.Duration) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.TokenCacheTTL = ttl
|
o.UserinfoCacheTTL = ttl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user