From 1e1e66f99aed2ccd46a9f67486f7208955039835 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 23 Sep 2021 21:01:26 +0200 Subject: [PATCH] add a new option that allows caches to be segregated see #399 Signed-off-by: Stefan Bodewig --- ChangeLog | 5 ++++- README.md | 22 ++++++++++++++++++++++ lib/resty/openidc.lua | 6 ++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbeb423..ad8850f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,10 +2,13 @@ - if lifecyle handlers return truthy values they cause the operation they are handlers of to fail; see #384; thanks to @arcivanov +- added opts.cache_segment as option to shard the cache used by token + introspection or JWT verification; see #399 + 09/22/2021 - made jwt_verify() and bearer_jwt_verify() use a separate cache named "jwt_verification" and introduced opts.jwt_verification_cache_ignore - to disable caching completely + to disable caching completely; see #399 12/05/2020 - fixed a session leak in access_token() and for a very unlikely diff --git a/README.md b/README.md index 7f902f0..b6ef300 100644 --- a/README.md +++ b/README.md @@ -299,6 +299,16 @@ local res, err, target, session = require("resty.openidc").authenticate(opts) session:close() ``` +## Caching of Introspection and JWT Verification Results + +Note the `jwt_verification` and `introspection` caches are shared +between all configured locations. If you are using locations with +different `opts` configuration the shared cache may allow a token that +is valid for only one location to be accepted by another if it is read +from the cache. In order to avoid cache confusion it is recommended to +set `opts.cache_segment` to unique strings for each set of related +locations. + ## Sample Configuration for OAuth 2.0 JWT Token Validation Sample `nginx.conf` configuration for verifying Bearer JWT Access Tokens against a pre-configured secret/key. @@ -379,6 +389,10 @@ lAc5Csj0o5Q+oEhPUAVBIF07m4rd0OvAVPOCQ2NJhQSL1oWASbf+fg== -- It may be necessary to force verification for a bearer token and ignore the existing cached -- verification results. If so you need to set set the jwt_verification_cache_ignore option to true. -- jwt_verification_cache_ignore = true + + -- optional name of a cache-segment if you need separate + -- caches for differently configured locations + -- cache_segment = 'api' } -- call bearer_jwt_verify for OAuth 2.0 JWT validation @@ -447,6 +461,10 @@ http { -- Defaults to "exp" - Controls the TTL of the introspection cache -- https://tools.ietf.org/html/rfc7662#section-2.2 -- introspection_expiry_claim = "exp" + + -- optional name of a cache-segment if you need separate + -- caches for differently configured locations + -- cache_segment = 'api' } -- call introspect for OAuth 2.0 Bearer Access Token validation @@ -547,6 +565,10 @@ http { -- It may be necessary to force an introspection call for an access_token and ignore the existing cached -- introspection results. If so you need to set set the introspection_cache_ignore option to true. -- introspection_cache_ignore = true + + -- optional name of a cache-segment if you need separate + -- caches for differently configured locations + -- cache_segment = 'api' } -- call introspect for OAuth 2.0 Bearer Access Token validation diff --git a/lib/resty/openidc.lua b/lib/resty/openidc.lua index f399980..51d1447 100644 --- a/lib/resty/openidc.lua +++ b/lib/resty/openidc.lua @@ -1629,7 +1629,8 @@ local function get_introspection_endpoint(opts) end local function get_introspection_cache_prefix(opts) - return (get_introspection_endpoint(opts) or 'nil-endpoint') .. ',' + return (opts.cache_segment and opts.cache_segment.gsub(',', '_') or 'DEFAULT') .. ',' + .. (get_introspection_endpoint(opts) or 'nil-endpoint') .. ',' .. (opts.client_id or 'no-client_id') .. ',' .. (opts.client_secret and 'secret' or 'no-client_secret') .. ':' end @@ -1738,7 +1739,8 @@ local function get_jwt_verification_cache_prefix(opts) for _, alg in ipairs(expected_algs) do signing_alg_values_expected = signing_alg_values_expected .. ',' .. alg end - return (opts.public_key or 'no-pubkey') .. ',' + return (opts.cache_segment and opts.cache_segment.gsub(',', '_') or 'DEFAULT') .. ',' + .. (opts.public_key or 'no-pubkey') .. ',' .. (opts.symmetric_key or 'no-symkey') .. ',' .. signing_alg_values_expected .. ':' end