mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 03:12:29 +00:00
feat: Adds option for a url to list of pub keys for jwt to pre-fetch.
The URL is a link to a json file having a mapping kid -> public key. The mapping can contain also certificates, which will be used to get the public key. The list is being updated before the cache-control max-age header value is reached, if such a header is returned from the server.
This commit is contained in:
@@ -13,8 +13,13 @@ local main_util = module:require "util";
|
||||
local ends_with = main_util.ends_with;
|
||||
local http_get_with_retry = main_util.http_get_with_retry;
|
||||
local extract_subdomain = main_util.extract_subdomain;
|
||||
local starts_with = main_util.starts_with;
|
||||
local cjson_safe = require 'cjson.safe'
|
||||
local timer = require "util.timer";
|
||||
local async = require "util.async";
|
||||
|
||||
local nr_retries = 3;
|
||||
local ssl = require "ssl";
|
||||
|
||||
-- TODO: Figure out a less arbitrary default cache size.
|
||||
local cacheSize = module:get_option_number("jwt_pubkey_cache_size", 128);
|
||||
@@ -34,6 +39,9 @@ function Util.new(module)
|
||||
self.appId = module:get_option_string("app_id");
|
||||
self.appSecret = module:get_option_string("app_secret");
|
||||
self.asapKeyServer = module:get_option_string("asap_key_server");
|
||||
-- A URL that will return json file with a mapping between kids and public keys
|
||||
-- If the response Cache-Control header we will respect it and refresh it
|
||||
self.cacheKeysUrl = module:get_option_string("cache_keys_url");
|
||||
self.signatureAlgorithm = module:get_option_string("signature_algorithm");
|
||||
self.allowEmptyToken = module:get_option_boolean("allow_empty_token");
|
||||
|
||||
@@ -109,6 +117,35 @@ function Util.new(module)
|
||||
return nil;
|
||||
end
|
||||
|
||||
if self.cacheKeysUrl then
|
||||
local update_keys_cache;
|
||||
update_keys_cache = async.runner(function (name)
|
||||
content, code, cache_for = http_get_with_retry(self.cacheKeysUrl, nr_retries);
|
||||
if content ~= nil then
|
||||
self.cachedKeys = {};
|
||||
-- Let's convert any certificate to public key
|
||||
for k, v in pairs(cjson_safe.decode(content)) do
|
||||
if starts_with(v, '-----BEGIN CERTIFICATE-----') then
|
||||
self.cachedKeys[k] = ssl.loadcertificate(v):pubkey();
|
||||
end
|
||||
end
|
||||
|
||||
if cache_for then
|
||||
cache_for = tonumber(cache_for);
|
||||
-- let's schedule new update 60 seconds before the cache expiring
|
||||
if cache_for > 60 then
|
||||
cache_for = cache_for - 60;
|
||||
end
|
||||
timer.add_task(cache_for, function ()
|
||||
update_keys_cache:run("update_keys_cache");
|
||||
end);
|
||||
end
|
||||
|
||||
end
|
||||
end);
|
||||
update_keys_cache:run("update_keys_cache");
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -202,7 +239,13 @@ function Util:process_and_verify_token(session, acceptedIssuers)
|
||||
if alg.sub(alg,1,2) ~= "RS" then
|
||||
return false, "not-allowed", "'kid' claim only support with RS family";
|
||||
end
|
||||
key = self:get_public_key(kid);
|
||||
|
||||
if self.cachedKeys and self.cachedKeys[kid] then
|
||||
key = self.cachedKeys[kid];
|
||||
else
|
||||
key = self:get_public_key(kid);
|
||||
end
|
||||
|
||||
if key == nil then
|
||||
return false, "not-allowed", "could not obtain public key";
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user