Refactor caches

Signed-off-by: Christian Richter <crichter@owncloud.com>
This commit is contained in:
Christian Richter
2023-04-12 15:40:18 +02:00
parent bc15b8a396
commit a900d0ed8d
4 changed files with 47 additions and 27 deletions

View File

@@ -43,13 +43,13 @@ import (
)
type StaticRouteHandler struct {
prefix string
proxy http.Handler
sidCache microstore.Store
accessTokenCache microstore.Store
logger log.Logger
config config.Config
oidcClient oidc.OIDCProvider
prefix string
proxy http.Handler
userInfoCache microstore.Store
sessionLookupCache microstore.Store
logger log.Logger
config config.Config
oidcClient oidc.OIDCProvider
}
// Server is the entrypoint for the server command.
@@ -62,7 +62,7 @@ func Server(cfg *config.Config) *cli.Command {
return configlog.ReturnFatal(parser.ParseConfig(cfg))
},
Action: func(c *cli.Context) error {
cache := store.Create(
userInfoCache := store.Create(
store.Store(cfg.OIDC.UserinfoCache.Store),
store.TTL(cfg.OIDC.UserinfoCache.TTL),
store.Size(cfg.OIDC.UserinfoCache.Size),
@@ -71,6 +71,15 @@ func Server(cfg *config.Config) *cli.Command {
microstore.Table(cfg.OIDC.UserinfoCache.Table),
)
sessionLookupCache := store.Create(
store.Store(cfg.OIDC.SessionLookupCache.Store),
store.TTL(cfg.OIDC.SessionLookupCache.TTL),
store.Size(cfg.OIDC.SessionLookupCache.Size),
microstore.Nodes(cfg.OIDC.SessionLookupCache.Nodes...),
microstore.Database(cfg.OIDC.SessionLookupCache.Database),
microstore.Table(cfg.OIDC.SessionLookupCache.Table),
)
logger := logging.Configure(cfg.Service.Name, cfg.Log)
err := tracing.Configure(cfg)
if err != nil {
@@ -122,20 +131,20 @@ func Server(cfg *config.Config) *cli.Command {
)
lh := StaticRouteHandler{
prefix: cfg.HTTP.Root,
sidCache: cache, // FIXME use correct cache
accessTokenCache: cache, // FIXME use correct cache
logger: logger,
config: *cfg,
oidcClient: oidcClient,
proxy: rp,
prefix: cfg.HTTP.Root,
userInfoCache: userInfoCache,
sessionLookupCache: sessionLookupCache,
logger: logger,
config: *cfg,
oidcClient: oidcClient,
proxy: rp,
}
if err != nil {
return fmt.Errorf("failed to initialize reverse proxy: %w", err)
}
{
middlewares := loadMiddlewares(ctx, logger, cfg, cache)
middlewares := loadMiddlewares(ctx, logger, cfg, userInfoCache, sessionLookupCache)
server, err := proxyHTTP.Server(
proxyHTTP.Handler(lh.handler()),
proxyHTTP.Logger(logger),
@@ -222,14 +231,14 @@ func (h *StaticRouteHandler) backchannelLogout(w http.ResponseWriter, r *http.Re
return
}
records, err := h.sidCache.Read(logoutToken.SessionId)
records, err := h.userInfoCache.Read(logoutToken.SessionId)
if errors.Is(err, microstore.ErrNotFound) || len(records) == 0 {
render.Status(r, http.StatusOK)
return
}
for _, record := range records {
err = h.accessTokenCache.Delete(string(record.Value))
err = h.sessionLookupCache.Delete(string(record.Value))
if errors.Is(err, microstore.ErrNotFound) {
render.Status(r, http.StatusOK)
return
@@ -239,7 +248,7 @@ func (h *StaticRouteHandler) backchannelLogout(w http.ResponseWriter, r *http.Re
render.Status(r, http.StatusOK)
}
func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config, cache microstore.Store) alice.Chain {
func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config, userInfoCache microstore.Store, sessionLookupCache microstore.Store) alice.Chain {
rolesClient := settingssvc.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient())
revaClient, err := pool.GetGatewayServiceClient(cfg.Reva.Address, cfg.Reva.GetRevaOptions()...)
if err != nil {
@@ -316,7 +325,8 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
authenticators = append(authenticators, middleware.NewOIDCAuthenticator(
middleware.Logger(logger),
middleware.Cache(cache),
middleware.UserInfoCache(userInfoCache),
middleware.SessionLookupCache(sessionLookupCache),
middleware.DefaultAccessTokenTTL(cfg.OIDC.UserinfoCache.TTL),
middleware.HTTPClient(oidcHTTPClient),
middleware.OIDCIss(cfg.OIDC.Issuer),

View File

@@ -106,6 +106,7 @@ type OIDC struct {
Insecure bool `yaml:"insecure" env:"OCIS_INSECURE;PROXY_OIDC_INSECURE" desc:"Disable TLS certificate validation for connections to the IDP. Note that this is not recommended for production environments."`
AccessTokenVerifyMethod string `yaml:"access_token_verify_method" env:"PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD" desc:"Sets how OIDC access tokens should be verified. Possible values are 'none' and 'jwt'. When using 'none', no special validation apart from using it for accessing the IPD's userinfo endpoint will be done. When using 'jwt', it tries to parse the access token as a jwt token and verifies the signature using the keys published on the IDP's 'jwks_uri'."`
UserinfoCache *Cache `yaml:"user_info_cache"`
SessionLookupCache *Cache `yaml:"session_lookup_cache"`
JWKS JWKS `yaml:"jwks"`
RewriteWellKnown bool `yaml:"rewrite_well_known" env:"PROXY_OIDC_REWRITE_WELLKNOWN" desc:"Enables rewriting the /.well-known/openid-configuration to the configured OIDC issuer. Needed by the Desktop Client, Android Client and iOS Client to discover the OIDC provider."`
}

View File

@@ -30,8 +30,8 @@ func NewOIDCAuthenticator(opts ...Option) *OIDCAuthenticator {
return &OIDCAuthenticator{
Logger: options.Logger,
userInfoCache: options.Cache,
sessionLookupCache: options.Cache,
userInfoCache: options.UserInfoCache,
sessionLookupCache: options.SessionLookupCache,
DefaultTokenCacheTTL: options.DefaultAccessTokenTTL,
HTTPClient: options.HTTPClient,
OIDCIss: options.OIDCIss,

View File

@@ -54,8 +54,10 @@ type Options struct {
EnableBasicAuth bool
// DefaultAccessTokenTTL is used to calculate the expiration when an access token has no expiration set
DefaultAccessTokenTTL time.Duration
// Cache sets the access token cache store
Cache store.Store
// UserInfoCache sets the access token cache store
UserInfoCache store.Store
// SessionLookupCache maps the session to a hashed jwt token
SessionLookupCache store.Store
// CredentialsByUserAgent sets the auth challenges on a per user-agent basis
CredentialsByUserAgent map[string]string
// AccessTokenVerifyMethod configures how access_tokens should be verified but the oidc_auth middleware.
@@ -191,10 +193,17 @@ func DefaultAccessTokenTTL(ttl time.Duration) Option {
}
}
// Cache provides a function to set the Cache
func Cache(val store.Store) Option {
// UserInfoCache provides a function to set the UserInfoCache
func UserInfoCache(val store.Store) Option {
return func(o *Options) {
o.Cache = val
o.UserInfoCache = val
}
}
// SessionLookupCache provides a function to set the SessionLookupCache
func SessionLookupCache(val store.Store) Option {
return func(o *Options) {
o.SessionLookupCache = val
}
}