in plugins/wasm-cpp/extensions/jwt_auth/plugin.cc [83:250]
bool PluginRootContext::parsePluginConfig(const json& configuration,
JwtAuthConfigRule& rule) {
std::unordered_set<std::string> name_set;
if (!JsonArrayIterate(
configuration, "consumers", [&](const json& consumer) -> bool {
Consumer c;
JSON_FIND_FIELD(consumer, name);
JSON_FIELD_VALUE_AS(std::string, consumer, name);
if (name_set.count(consumer_name) != 0) {
LOG_WARN("consumer already exists: " + consumer_name);
return false;
}
c.name = consumer_name;
JSON_FIND_FIELD(consumer, jwks);
JSON_FIELD_VALUE_AS(std::string, consumer, jwks);
c.jwks = google::jwt_verify::Jwks::createFrom(
consumer_jwks, google::jwt_verify::Jwks::JWKS);
if (c.jwks->getStatus() != Status::Ok) {
LOG_WARN(absl::StrFormat(
"jwks is invalid, consumer:%s, status:%s, jwks:%s",
consumer_name,
google::jwt_verify::getStatusString(c.jwks->getStatus()),
consumer_jwks));
return false;
}
std::unordered_map<std::string, std::string> claims;
auto consumer_claims_json = consumer.find("claims");
if (consumer_claims_json != consumer.end()) {
JSON_FIELD_VALUE_AS(Wasm::Common::JsonObject, consumer, claims);
if (!JsonObjectIterate(
consumer_claims, [&](std::string key) -> bool {
auto claims_claim_json = consumer_claims.find(key);
JSON_FIELD_VALUE_AS(std::string, claims, claim);
claims.emplace(std::make_pair(
key, Wasm::Common::trim(claims_claim)));
return true;
})) {
LOG_WARN("failed to parse 'claims' in consumer: " +
consumer_name);
return false;
}
}
auto consumer_issuer_json = consumer.find("issuer");
if (consumer_issuer_json != consumer.end()) {
JSON_FIELD_VALUE_AS(std::string, consumer, issuer);
claims.emplace(
std::make_pair("iss", Wasm::Common::trim(consumer_issuer)));
}
c.allowd_claims = std::move(claims);
std::vector<FromHeader> from_headers;
if (!JsonArrayIterate(
consumer, "from_headers",
[&](const json& from_header) -> bool {
JSON_FIND_FIELD(from_header, name);
JSON_FIELD_VALUE_AS(std::string, from_header, name);
std::string header_value_prefix;
auto from_header_value_prefix_json =
from_header.find("value_prefix");
if (from_header_value_prefix_json != from_header.end()) {
JSON_FIELD_VALUE_AS(std::string, from_header,
value_prefix);
header_value_prefix = from_header_value_prefix;
}
from_headers.push_back(
FromHeader{from_header_name, header_value_prefix});
return true;
})) {
LOG_WARN("failed to parse 'from_headers' in consumer: " +
consumer_name);
return false;
}
std::vector<std::string> from_params;
if (!JsonArrayIterate(consumer, "from_params",
[&](const json& from_param_json) -> bool {
JSON_VALUE_AS(std::string, from_param_json,
from_param, "invalid item");
from_params.push_back(from_param);
return true;
})) {
LOG_WARN("failed to parse 'from_params' in consumer: " +
consumer_name);
return false;
}
std::vector<std::string> from_cookies;
if (!JsonArrayIterate(consumer, "from_cookies",
[&](const json& from_cookie_json) -> bool {
JSON_VALUE_AS(std::string, from_cookie_json,
from_cookie, "invalid item");
from_cookies.push_back(from_cookie);
return true;
})) {
LOG_WARN("failed to parse 'from_cookies' in consumer: " +
consumer_name);
return false;
}
if (!from_headers.empty() || !from_params.empty() ||
!from_cookies.empty()) {
c.from_headers = std::move(from_headers);
c.from_params = std::move(from_params);
c.from_cookies = std::move(from_cookies);
}
std::unordered_map<std::string, ClaimToHeader> claims_to_headers;
if (!JsonArrayIterate(
consumer, "claims_to_headers",
[&](const json& item_json) -> bool {
JSON_VALUE_AS(Wasm::Common::JsonObject, item_json, item,
"invalid item");
JSON_FIND_FIELD(item, claim);
JSON_FIELD_VALUE_AS(std::string, item, claim);
auto c2h_it = claims_to_headers.find(item_claim);
if (c2h_it != claims_to_headers.end()) {
LOG_WARN("claim to header already exists: " +
item_claim);
return false;
}
auto& c2h = claims_to_headers[item_claim];
JSON_FIND_FIELD(item, header);
JSON_FIELD_VALUE_AS(std::string, item, header);
c2h.header = std::move(item_header);
auto item_override_json = item.find("override");
if (item_override_json != item.end()) {
JSON_FIELD_VALUE_AS(bool, item, override);
c2h.override = item_override;
}
return true;
})) {
LOG_WARN("failed to parse 'claims_to_headers' in consumer: " +
consumer_name);
return false;
}
c.claims_to_headers = std::move(claims_to_headers);
auto consumer_clock_skew_seconds_json =
consumer.find("clock_skew_seconds");
if (consumer_clock_skew_seconds_json != consumer.end()) {
JSON_FIELD_VALUE_AS(uint64_t, consumer, clock_skew_seconds);
c.clock_skew = consumer_clock_skew_seconds;
}
auto consumer_keep_token_json = consumer.find("keep_token");
if (consumer_keep_token_json != consumer.end()) {
JSON_FIELD_VALUE_AS(bool, consumer, keep_token);
c.keep_token = consumer_keep_token;
}
c.extractor = Extractor::create(c);
rule.consumers.push_back(std::move(c));
name_set.insert(consumer_name);
return true;
})) {
LOG_WARN("failed to parse configuration for consumers.");
return false;
}
if (rule.consumers.empty()) {
LOG_INFO("at least one consumer has to be configured for a rule.");
return false;
}
std::vector<std::string> enable_headers;
if (!JsonArrayIterate(configuration, "enable_headers",
[&](const json& enable_header_json) -> bool {
JSON_VALUE_AS(std::string, enable_header_json,
enable_header, "invalid item");
enable_headers.push_back(enable_header);
return true;
})) {
LOG_WARN("failed to parse 'enable_headers'");
return false;
}
rule.enable_headers = std::move(enable_headers);
return true;
}