|
34 | 34 | tokenMap *shardedTokenMap |
35 | 35 | // provides thread-safe access to an underlying map of tokens |
36 | 36 | revokedTokens *RevokedTokensMap |
| 37 | + // for canceling internal long-lived context |
| 38 | + cancelCtx context.CancelFunc |
37 | 39 | } |
38 | 40 |
|
39 | 41 | RevokedTokensMap struct { |
@@ -64,46 +66,76 @@ const ( |
64 | 66 | TokenParserInitTimeout = 10 * time.Second |
65 | 67 | ) |
66 | 68 |
|
| 69 | +// Client defaults for issuer requests |
| 70 | +// Used for JWKS URL discovery and fetching |
| 71 | +// See cmn/client.go |
| 72 | +const ( |
| 73 | + // KeyCacheDialTimeout and KeyCacheTimeout are set for faster proxy startup in case of an unresponsive issuer service |
| 74 | + KeyCacheDialTimeout = 5 * time.Second |
| 75 | + KeyCacheTimeout = 10 * time.Second |
| 76 | + |
| 77 | + // KeyCacheIdleConnsPerHost overrides AIS client settings to match http.Transport.DefaultMaxIdleConnsPerHost |
| 78 | + // Because of cached key sets, we don't expect to need idle connections to the same issuer host |
| 79 | + KeyCacheIdleConnsPerHost = 2 |
| 80 | + // KeyCacheMaxIdleConnsLimit caps the maximum idle conns based on number of allowed issuers |
| 81 | + KeyCacheMaxIdleConnsLimit = 16 |
| 82 | +) |
| 83 | + |
67 | 84 | ///////////////// |
68 | 85 | // authManager // |
69 | 86 | ///////////////// |
70 | 87 |
|
71 | 88 | func newAuthManager(config *cmn.Config) *authManager { |
72 | | - parser := tok.NewTokenParser(&config.Auth, getJWKSClientConf(config), nil) |
73 | | - cancelCtx, cancel := context.WithTimeout(context.Background(), TokenParserInitTimeout) |
| 89 | + rootCtx, rootCancel := context.WithCancel(context.Background()) |
| 90 | + keyCacheClient := newKeyCacheClient(config) |
| 91 | + keyCacheManager := tok.NewKeyCacheManager(config.Auth.OIDC, keyCacheClient, nil) |
| 92 | + keyCacheManager.Init(rootCtx) |
| 93 | + timeoutCtx, cancel := context.WithTimeout(context.Background(), TokenParserInitTimeout) |
74 | 94 | defer cancel() |
75 | | - if err := parser.InitKeyCache(cancelCtx); err != nil { |
76 | | - // TODO: Add dynamic cache registration so we can proceed from this init failure and resolve later |
77 | | - cos.ExitLogf("Auth manager error: %v", err) |
| 95 | + if err := keyCacheManager.PopulateJWKSCache(timeoutCtx); err != nil { |
| 96 | + nlog.Errorf("Errors occurred while pre-populating JWKS key cache: %v", err) |
78 | 97 | } |
79 | 98 | return &authManager{ |
80 | | - tokenParser: parser, |
| 99 | + tokenParser: tok.NewTokenParser(&config.Auth, keyCacheManager), |
81 | 100 | tokenMap: newShardedTokenMap(TokenMapShardExponent), |
82 | 101 | revokedTokens: newRevokedTokensMap(), |
| 102 | + cancelCtx: rootCancel, |
83 | 103 | } |
84 | 104 | } |
85 | 105 |
|
86 | | -// Define the config for JWKS client used by the token parser |
87 | | -func getJWKSClientConf(config *cmn.Config) (jwksConf *tok.JWKSClientConf) { |
| 106 | +// Define the client used by the key cache manager for contacting token issuers |
| 107 | +func newKeyCacheClient(config *cmn.Config) *http.Client { |
| 108 | + var tls cmn.TLSArgs |
88 | 109 | // Set our own certificate, key, and verification settings from AIS network config |
89 | | - var tlsArgs cmn.TLSArgs |
90 | 110 | if config.Net.HTTP.UseHTTPS { |
91 | | - tlsArgs = config.Net.HTTP.ToTLS() |
| 111 | + tls = config.Net.HTTP.ToTLS() |
92 | 112 | } else { |
93 | | - tlsArgs = cmn.TLSArgs{ |
| 113 | + tls = cmn.TLSArgs{ |
94 | 114 | SkipVerify: false, |
95 | 115 | } |
96 | 116 | } |
97 | | - if config.Auth.OIDC != nil { |
98 | | - // Define the trusted CA for issuers |
99 | | - tlsArgs.ClientCA = config.Auth.OIDC.IssuerCA |
| 117 | + // Override the trusted CA for issuers if location provided |
| 118 | + if config.Auth.OIDC != nil && config.Auth.OIDC.IssuerCA != "" { |
| 119 | + tls.ClientCA = config.Auth.OIDC.IssuerCA |
| 120 | + } |
| 121 | + // Key cache client should never need more idle connections than configured issuers |
| 122 | + // Set MaxIdleConns to limit the idle connections kept to issuers when we don't expect any subsequent requests |
| 123 | + maxIdleConns := KeyCacheIdleConnsPerHost |
| 124 | + if config.Auth.OIDC != nil && len(config.Auth.OIDC.AllowedIssuers) > maxIdleConns { |
| 125 | + maxIdleConns = min(len(config.Auth.OIDC.AllowedIssuers), KeyCacheMaxIdleConnsLimit) |
100 | 126 | } |
101 | 127 |
|
102 | | - // Leave transport args empty for default config |
103 | | - clientConf := &tok.JWKSClientConf{ |
104 | | - TLSArgs: &tlsArgs, |
| 128 | + transport := cmn.TransportArgs{ |
| 129 | + DialTimeout: KeyCacheDialTimeout, |
| 130 | + Timeout: KeyCacheTimeout, |
| 131 | + IdleConnsPerHost: KeyCacheIdleConnsPerHost, |
| 132 | + MaxIdleConns: maxIdleConns, |
105 | 133 | } |
106 | | - return clientConf |
| 134 | + return cmn.NewClientTLS(transport, tls, false) |
| 135 | +} |
| 136 | + |
| 137 | +func (a *authManager) stop() { |
| 138 | + a.cancelCtx() |
107 | 139 | } |
108 | 140 |
|
109 | 141 | // Add tokens to the list of invalid ones and clean up the list from expired tokens. |
|
0 commit comments