-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Extract JWT claims as string lists under request.auth.claims[] for RBAC #1906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3e00200
dfd4566
6295f68
84a4fe3
7434c90
97f2bc9
67ee2fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,9 +25,6 @@ namespace { | |
| // The JWT audience key name | ||
| static const std::string kJwtAudienceKey = "aud"; | ||
|
|
||
| // The JWT groups key name | ||
| static const std::string kJwtGroupsKey = "groups"; | ||
|
|
||
| // Extract JWT audience into the JwtPayload. | ||
| // This function should to be called after the claims are extracted. | ||
| void ExtractJwtAudience( | ||
|
|
@@ -52,24 +49,22 @@ void ExtractJwtAudience( | |
| } | ||
| } | ||
|
|
||
| // Extract JWT groups into the JwtPayload. | ||
| // Extract JWT claim as a string list | ||
| // This function should to be called after the claims are extracted. | ||
| void ExtractJwtGroups( | ||
| const Envoy::Json::Object& obj, | ||
| void ExtractStringList( | ||
| const std::string& key, const Envoy::Json::Object& obj, | ||
| const ::google::protobuf::Map< ::std::string, ::std::string>& claims, | ||
| istio::authn::JwtPayload* payload) { | ||
| const std::string& key = kJwtGroupsKey; | ||
| // "groups" can be either string array or string. | ||
| std::vector<std::string>& list) { | ||
| // First, try as string | ||
| if (claims.count(key) > 0) { | ||
| payload->add_groups(claims.at(key)); | ||
| list.push_back(claims.at(key)); | ||
| return; | ||
| } | ||
| // Next, try as string array | ||
| try { | ||
| std::vector<std::string> group_vector = obj.getStringArray(key); | ||
| for (const std::string group : group_vector) { | ||
| payload->add_groups(group); | ||
| std::vector<std::string> vector = obj.getStringArray(key); | ||
| for (const std::string v : vector) { | ||
| list.push_back(v); | ||
| } | ||
| } catch (Json::Exception& e) { | ||
| // Not convertable to string array | ||
|
|
@@ -92,7 +87,7 @@ bool AuthnUtils::ProcessJwtPayload(const std::string& payload_str, | |
| ::google::protobuf::Map< ::std::string, ::std::string>* claims = | ||
| payload->mutable_claims(); | ||
|
|
||
| // Extract claims | ||
| // Extract claims as strings | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you are doing it for all claims, do you want to replace the logic here with what you had for ExtractStringList()?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ExtractStringList() extracts a string list whereas the code here only extracts a string. So the logic for ExtractStringList() is not applied here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean, you can apply the same logic, first try as a string, then string list, here. With the current way, you actually do it twice, first cast all claims to string in this function, then cast them to string list in ExtractStringList function.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before ExtractStringList(key, *json_obj, *claims, list) is called, claims must have been extracted. Hence the separation of two loops (one at line 93, the other at line 123). |
||
| json_obj->iterate( | ||
| [payload](const std::string& key, const Json::Object& obj) -> bool { | ||
| ::google::protobuf::Map< ::std::string, ::std::string>* claims = | ||
|
|
@@ -110,8 +105,7 @@ bool AuthnUtils::ProcessJwtPayload(const std::string& payload_str, | |
| // Extract audience | ||
| // ExtractJwtAudience() should be called after claims are extracted. | ||
| ExtractJwtAudience(*json_obj, payload->claims(), payload); | ||
| // ExtractJwtGroups() should be called after claims are extracted. | ||
| ExtractJwtGroups(*json_obj, payload->claims(), payload); | ||
|
|
||
| // Build user | ||
| if (claims->count("iss") > 0 && claims->count("sub") > 0) { | ||
| payload->set_user((*claims)["iss"] + "/" + (*claims)["sub"]); | ||
|
|
@@ -120,6 +114,18 @@ bool AuthnUtils::ProcessJwtPayload(const std::string& payload_str, | |
| if (claims->count("azp") > 0) { | ||
| payload->set_presenter((*claims)["azp"]); | ||
| } | ||
|
|
||
| // Extract claims as lists of strings for RBAC list matcher | ||
| json_obj->iterate([json_obj, payload, claims](const std::string& key, | ||
| const Json::Object&) -> bool { | ||
| auto* claim_lists = payload->mutable_claim_string_lists(); | ||
| std::vector<std::string> list; | ||
| ExtractStringList(key, *json_obj, *claims, list); | ||
| for (auto s : list) { | ||
| (*claim_lists)[key].add_list(s); | ||
| } | ||
| return true; | ||
| }); | ||
| return true; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still need
kJwtGroupsKeyin line 29?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I have removed it. Thanks.