{"action":"created","comment":{"url":"https://api.github.com/repos/istio/proxy/pulls/comments/176609922","pull_request_review_id":106344515,"id":176609922,"diff_hunk":"@@ -0,0 +1,108 @@\n+/* Copyright 2018 Istio Authors. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *    http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+#include \"authn_utils.h\"\n+#include \"common/json/json_loader.h\"\n+#include \"src/envoy/http/jwt_auth/jwt.h\"\n+\n+namespace Envoy {\n+namespace Http {\n+namespace Istio {\n+namespace AuthN {\n+\n+bool AuthnUtils::GetJWTPayloadFromHeaders(\n+    const HeaderMap& headers, const LowerCaseString& jwt_payload_key,\n+    istio::authn::JwtPayload* payload) {\n+  const HeaderEntry* entry = headers.get(jwt_payload_key);\n+  if (!entry) {\n+    ENVOY_LOG(error, \"{}: no JwtPayloadKey entry {} in the header\",\n+              __FUNCTION__, jwt_payload_key.get());\n+    return false;\n+  }\n+  std::string value(entry->value().c_str(), entry->value().size());\n+  // JwtAuth::Base64UrlDecode() is different from Base64::decode().\n+  std::string payload_str = JwtAuth::Base64UrlDecode(value);\n+  // Return an empty string if Base64 decode fails.\n+  if (payload_str.empty()) {\n+    ENVOY_LOG(error, \"Invalid {} header, invalid base64: {}\",\n+              jwt_payload_key.get(), value);\n+    return false;\n+  }\n+  ::google::protobuf::Map< ::std::string, ::std::string>* claims =\n+      payload->mutable_claims();\n+  try {\n+    auto json_obj = Json::Factory::loadFromString(payload_str);\n+    ENVOY_LOG(debug, \"{}: json object is {}\", __FUNCTION__,\n+              json_obj->asJsonString());\n+    json_obj->iterate([claims, &payload](const std::string& key,\n+                                         const Json::Object& obj) -> bool {\n+      ENVOY_LOG(debug, \"{}: key is {}\", __FUNCTION__, key);\n+      try {\n+        if (key == \"aud\") {\n+          // \"aud\" can be either string array or string.\n+          // Try as string array, read it as empty array if doesn't exist.\n+          std::vector<std::string> aud_vector;\n+          try {\n+            aud_vector = obj.getStringArray(key, true);\n+          } catch (Json::Exception& e) {\n+            // Try as string\n+            try {\n+              auto audience = obj.asString();\n+              aud_vector.push_back(audience);\n+            } catch (Json::Exception& e) {\n+              ENVOY_LOG(error,\n+                        \"{}: an exception is thrown when get audience as \"\n+                        \"string. The exception is: {}\",\n+                        __FUNCTION__, e.what());\n+            }\n+          }\n+          for (size_t i = 0; i < aud_vector.size(); i++) {\n+            payload->add_audiences(aud_vector[i]);\n+          }\n+        } else {\n+          // will throw execption if value type is not string.\n+          // In current implementation, only string objects are extracted into\n+          // claims.\n+          (*claims)[key] = obj.asString();\n+        }\n+      } catch (...) {\n+      }\n+      return true;\n+    });\n+  } catch (...) {\n+    ENVOY_LOG(error, \"Invalid {} header, invalid json: {}\",\n+              jwt_payload_key.get(), payload_str);\n+    return false;\n+  }\n+\n+  if (payload->mutable_claims()->empty()) {","path":"src/envoy/http/authn/authn_utils.cc","position":90,"original_position":90,"commit_id":"88170b5b84c8f7011993f252f88653f9361d295c","original_commit_id":"88170b5b84c8f7011993f252f88653f9361d295c","user":{"login":"qiwzhang","id":11790727,"avatar_url":"https://avatars0.githubusercontent.com/u/11790727?v=4","gravatar_id":"","url":"https://api.github.com/users/qiwzhang","html_url":"https://github.com/qiwzhang","followers_url":"https://api.github.com/users/qiwzhang/followers","following_url":"https://api.github.com/users/qiwzhang/following{/other_user}","gists_url":"https://api.github.com/users/qiwzhang/gists{/gist_id}","starred_url":"https://api.github.com/users/qiwzhang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qiwzhang/subscriptions","organizations_url":"https://api.github.com/users/qiwzhang/orgs","repos_url":"https://api.github.com/users/qiwzhang/repos","events_url":"https://api.github.com/users/qiwzhang/events{/privacy}","received_events_url":"https://api.github.com/users/qiwzhang/received_events","type":"User","site_admin":false},"body":"why do you need to call mutable_?","created_at":"2018-03-23T00:18:40Z","updated_at":"2018-03-23T00:29:13Z","html_url":"https://github.com/istio/proxy/pull/1216#discussion_r176609922","pull_request_url":"https://api.github.com/repos/istio/proxy/pulls/1216","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/istio/proxy/pulls/comments/176609922"},"html":{"href":"https://github.com/istio/proxy/pull/1216#discussion_r176609922"},"pull_request":{"href":"https://api.github.com/repos/istio/proxy/pulls/1216"}}},"pull_request":{"url":"https://api.github.com/repos/istio/proxy/pulls/1216","id":175675198,"html_url":"https://github.com/istio/proxy/pull/1216","diff_url":"https://github.com/istio/proxy/pull/1216.diff","patch_url":"https://github.com/istio/proxy/pull/1216.patch","issue_url":"https://api.github.com/repos/istio/proxy/issues/1216","number":1216,"state":"open","locked":false,"title":"Validate JWTs in Istio authentication policy using the output of jwt-auth","user":{"login":"lei-tang","id":32078630,"avatar_url":"https://avatars1.githubusercontent.com/u/32078630?v=4","gravatar_id":"","url":"https://api.github.com/users/lei-tang","html_url":"https://github.com/lei-tang","followers_url":"https://api.github.com/users/lei-tang/followers","following_url":"https://api.github.com/users/lei-tang/following{/other_user}","gists_url":"https://api.github.com/users/lei-tang/gists{/gist_id}","starred_url":"https://api.github.com/users/lei-tang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lei-tang/subscriptions","organizations_url":"https://api.github.com/users/lei-tang/orgs","repos_url":"https://api.github.com/users/lei-tang/repos","events_url":"https://api.github.com/users/lei-tang/events{/privacy}","received_events_url":"https://api.github.com/users/lei-tang/received_events","type":"User","site_admin":false},"body":"**What this PR does / why we need it**:  POC: validate JWTs in Istio authentication policy using the output of jwt-auth\r\n\r\n**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #1214 \r\n\r\n**Special notes for your reviewer**:\r\n\r\n**Release note**:\r\n<!--  Steps to write your release note:\r\n1. Use the release-note-* labels to set the release note state (if you have access)\r\n2. Enter your extended release note in the below block; leaving it blank means using the PR title as the release note. If no release note is required, just write `NONE`.\r\n-->\r\n```release-note\r\n```\r\n","created_at":"2018-03-17T01:05:11Z","updated_at":"2018-03-23T00:29:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d40ed242f5684559d67513ae76166e55dc89a21a","assignee":{"login":"diemtvu","id":25132401,"avatar_url":"https://avatars0.githubusercontent.com/u/25132401?v=4","gravatar_id":"","url":"https://api.github.com/users/diemtvu","html_url":"https://github.com/diemtvu","followers_url":"https://api.github.com/users/diemtvu/followers","following_url":"https://api.github.com/users/diemtvu/following{/other_user}","gists_url":"https://api.github.com/users/diemtvu/gists{/gist_id}","starred_url":"https://api.github.com/users/diemtvu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diemtvu/subscriptions","organizations_url":"https://api.github.com/users/diemtvu/orgs","repos_url":"https://api.github.com/users/diemtvu/repos","events_url":"https://api.github.com/users/diemtvu/events{/privacy}","received_events_url":"https://api.github.com/users/diemtvu/received_events","type":"User","site_admin":false},"assignees":[{"login":"diemtvu","id":25132401,"avatar_url":"https://avatars0.githubusercontent.com/u/25132401?v=4","gravatar_id":"","url":"https://api.github.com/users/diemtvu","html_url":"https://github.com/diemtvu","followers_url":"https://api.github.com/users/diemtvu/followers","following_url":"https://api.github.com/users/diemtvu/following{/other_user}","gists_url":"https://api.github.com/users/diemtvu/gists{/gist_id}","starred_url":"https://api.github.com/users/diemtvu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diemtvu/subscriptions","organizations_url":"https://api.github.com/users/diemtvu/orgs","repos_url":"https://api.github.com/users/diemtvu/repos","events_url":"https://api.github.com/users/diemtvu/events{/privacy}","received_events_url":"https://api.github.com/users/diemtvu/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":712050392,"url":"https://api.github.com/repos/istio/proxy/labels/cla:%20yes","name":"cla: yes","color":"1d76db","default":false},{"id":696479044,"url":"https://api.github.com/repos/istio/proxy/labels/lgtm","name":"lgtm","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/istio/proxy/pulls/1216/commits","review_comments_url":"https://api.github.com/repos/istio/proxy/pulls/1216/comments","review_comment_url":"https://api.github.com/repos/istio/proxy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/istio/proxy/issues/1216/comments","statuses_url":"https://api.github.com/repos/istio/proxy/statuses/88170b5b84c8f7011993f252f88653f9361d295c","head":{"label":"lei-tang:interprete_jwt_auth_output","ref":"interprete_jwt_auth_output","sha":"88170b5b84c8f7011993f252f88653f9361d295c","user":{"login":"lei-tang","id":32078630,"avatar_url":"https://avatars1.githubusercontent.com/u/32078630?v=4","gravatar_id":"","url":"https://api.github.com/users/lei-tang","html_url":"https://github.com/lei-tang","followers_url":"https://api.github.com/users/lei-tang/followers","following_url":"https://api.github.com/users/lei-tang/following{/other_user}","gists_url":"https://api.github.com/users/lei-tang/gists{/gist_id}","starred_url":"https://api.github.com/users/lei-tang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lei-tang/subscriptions","organizations_url":"https://api.github.com/users/lei-tang/orgs","repos_url":"https://api.github.com/users/lei-tang/repos","events_url":"https://api.github.com/users/lei-tang/events{/privacy}","received_events_url":"https://api.github.com/users/lei-tang/received_events","type":"User","site_admin":false},"repo":{"id":117921130,"name":"proxy","full_name":"lei-tang/proxy","owner":{"login":"lei-tang","id":32078630,"avatar_url":"https://avatars1.githubusercontent.com/u/32078630?v=4","gravatar_id":"","url":"https://api.github.com/users/lei-tang","html_url":"https://github.com/lei-tang","followers_url":"https://api.github.com/users/lei-tang/followers","following_url":"https://api.github.com/users/lei-tang/following{/other_user}","gists_url":"https://api.github.com/users/lei-tang/gists{/gist_id}","starred_url":"https://api.github.com/users/lei-tang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lei-tang/subscriptions","organizations_url":"https://api.github.com/users/lei-tang/orgs","repos_url":"https://api.github.com/users/lei-tang/repos","events_url":"https://api.github.com/users/lei-tang/events{/privacy}","received_events_url":"https://api.github.com/users/lei-tang/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lei-tang/proxy","description":"The Istio proxy components.","fork":true,"url":"https://api.github.com/repos/lei-tang/proxy","forks_url":"https://api.github.com/repos/lei-tang/proxy/forks","keys_url":"https://api.github.com/repos/lei-tang/proxy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lei-tang/proxy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lei-tang/proxy/teams","hooks_url":"https://api.github.com/repos/lei-tang/proxy/hooks","issue_events_url":"https://api.github.com/repos/lei-tang/proxy/issues/events{/number}","events_url":"https://api.github.com/repos/lei-tang/proxy/events","assignees_url":"https://api.github.com/repos/lei-tang/proxy/assignees{/user}","branches_url":"https://api.github.com/repos/lei-tang/proxy/branches{/branch}","tags_url":"https://api.github.com/repos/lei-tang/proxy/tags","blobs_url":"https://api.github.com/repos/lei-tang/proxy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lei-tang/proxy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lei-tang/proxy/git/refs{/sha}","trees_url":"https://api.github.com/repos/lei-tang/proxy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lei-tang/proxy/statuses/{sha}","languages_url":"https://api.github.com/repos/lei-tang/proxy/languages","stargazers_url":"https://api.github.com/repos/lei-tang/proxy/stargazers","contributors_url":"https://api.github.com/repos/lei-tang/proxy/contributors","subscribers_url":"https://api.github.com/repos/lei-tang/proxy/subscribers","subscription_url":"https://api.github.com/repos/lei-tang/proxy/subscription","commits_url":"https://api.github.com/repos/lei-tang/proxy/commits{/sha}","git_commits_url":"https://api.github.com/repos/lei-tang/proxy/git/commits{/sha}","comments_url":"https://api.github.com/repos/lei-tang/proxy/comments{/number}","issue_comment_url":"https://api.github.com/repos/lei-tang/proxy/issues/comments{/number}","contents_url":"https://api.github.com/repos/lei-tang/proxy/contents/{+path}","compare_url":"https://api.github.com/repos/lei-tang/proxy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lei-tang/proxy/merges","archive_url":"https://api.github.com/repos/lei-tang/proxy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lei-tang/proxy/downloads","issues_url":"https://api.github.com/repos/lei-tang/proxy/issues{/number}","pulls_url":"https://api.github.com/repos/lei-tang/proxy/pulls{/number}","milestones_url":"https://api.github.com/repos/lei-tang/proxy/milestones{/number}","notifications_url":"https://api.github.com/repos/lei-tang/proxy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lei-tang/proxy/labels{/name}","releases_url":"https://api.github.com/repos/lei-tang/proxy/releases{/id}","deployments_url":"https://api.github.com/repos/lei-tang/proxy/deployments","created_at":"2018-01-18T02:33:39Z","updated_at":"2018-03-16T18:15:23Z","pushed_at":"2018-03-22T23:43:21Z","git_url":"git://github.com/lei-tang/proxy.git","ssh_url":"git@github.com:lei-tang/proxy.git","clone_url":"https://github.com/lei-tang/proxy.git","svn_url":"https://github.com/lei-tang/proxy","homepage":"","size":2431,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"istio:master","ref":"master","sha":"a352024400d25f0a8009f0b734eb278519a5f09b","user":{"login":"istio","id":23534644,"avatar_url":"https://avatars1.githubusercontent.com/u/23534644?v=4","gravatar_id":"","url":"https://api.github.com/users/istio","html_url":"https://github.com/istio","followers_url":"https://api.github.com/users/istio/followers","following_url":"https://api.github.com/users/istio/following{/other_user}","gists_url":"https://api.github.com/users/istio/gists{/gist_id}","starred_url":"https://api.github.com/users/istio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/istio/subscriptions","organizations_url":"https://api.github.com/users/istio/orgs","repos_url":"https://api.github.com/users/istio/repos","events_url":"https://api.github.com/users/istio/events{/privacy}","received_events_url":"https://api.github.com/users/istio/received_events","type":"Organization","site_admin":false},"repo":{"id":75322405,"name":"proxy","full_name":"istio/proxy","owner":{"login":"istio","id":23534644,"avatar_url":"https://avatars1.githubusercontent.com/u/23534644?v=4","gravatar_id":"","url":"https://api.github.com/users/istio","html_url":"https://github.com/istio","followers_url":"https://api.github.com/users/istio/followers","following_url":"https://api.github.com/users/istio/following{/other_user}","gists_url":"https://api.github.com/users/istio/gists{/gist_id}","starred_url":"https://api.github.com/users/istio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/istio/subscriptions","organizations_url":"https://api.github.com/users/istio/orgs","repos_url":"https://api.github.com/users/istio/repos","events_url":"https://api.github.com/users/istio/events{/privacy}","received_events_url":"https://api.github.com/users/istio/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/istio/proxy","description":"The Istio proxy components.","fork":false,"url":"https://api.github.com/repos/istio/proxy","forks_url":"https://api.github.com/repos/istio/proxy/forks","keys_url":"https://api.github.com/repos/istio/proxy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/istio/proxy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/istio/proxy/teams","hooks_url":"https://api.github.com/repos/istio/proxy/hooks","issue_events_url":"https://api.github.com/repos/istio/proxy/issues/events{/number}","events_url":"https://api.github.com/repos/istio/proxy/events","assignees_url":"https://api.github.com/repos/istio/proxy/assignees{/user}","branches_url":"https://api.github.com/repos/istio/proxy/branches{/branch}","tags_url":"https://api.github.com/repos/istio/proxy/tags","blobs_url":"https://api.github.com/repos/istio/proxy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/istio/proxy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/istio/proxy/git/refs{/sha}","trees_url":"https://api.github.com/repos/istio/proxy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/istio/proxy/statuses/{sha}","languages_url":"https://api.github.com/repos/istio/proxy/languages","stargazers_url":"https://api.github.com/repos/istio/proxy/stargazers","contributors_url":"https://api.github.com/repos/istio/proxy/contributors","subscribers_url":"https://api.github.com/repos/istio/proxy/subscribers","subscription_url":"https://api.github.com/repos/istio/proxy/subscription","commits_url":"https://api.github.com/repos/istio/proxy/commits{/sha}","git_commits_url":"https://api.github.com/repos/istio/proxy/git/commits{/sha}","comments_url":"https://api.github.com/repos/istio/proxy/comments{/number}","issue_comment_url":"https://api.github.com/repos/istio/proxy/issues/comments{/number}","contents_url":"https://api.github.com/repos/istio/proxy/contents/{+path}","compare_url":"https://api.github.com/repos/istio/proxy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/istio/proxy/merges","archive_url":"https://api.github.com/repos/istio/proxy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/istio/proxy/downloads","issues_url":"https://api.github.com/repos/istio/proxy/issues{/number}","pulls_url":"https://api.github.com/repos/istio/proxy/pulls{/number}","milestones_url":"https://api.github.com/repos/istio/proxy/milestones{/number}","notifications_url":"https://api.github.com/repos/istio/proxy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/istio/proxy/labels{/name}","releases_url":"https://api.github.com/repos/istio/proxy/releases{/id}","deployments_url":"https://api.github.com/repos/istio/proxy/deployments","created_at":"2016-12-01T18:51:04Z","updated_at":"2018-03-23T00:02:53Z","pushed_at":"2018-03-23T00:06:11Z","git_url":"git://github.com/istio/proxy.git","ssh_url":"git@github.com:istio/proxy.git","clone_url":"https://github.com/istio/proxy.git","svn_url":"https://github.com/istio/proxy","homepage":"","size":2273,"stargazers_count":114,"watchers_count":114,"language":"C++","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":81,"mirror_url":null,"archived":false,"open_issues_count":36,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":81,"open_issues":36,"watchers":114,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/istio/proxy/pulls/1216"},"html":{"href":"https://github.com/istio/proxy/pull/1216"},"issue":{"href":"https://api.github.com/repos/istio/proxy/issues/1216"},"comments":{"href":"https://api.github.com/repos/istio/proxy/issues/1216/comments"},"review_comments":{"href":"https://api.github.com/repos/istio/proxy/pulls/1216/comments"},"review_comment":{"href":"https://api.github.com/repos/istio/proxy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/istio/proxy/pulls/1216/commits"},"statuses":{"href":"https://api.github.com/repos/istio/proxy/statuses/88170b5b84c8f7011993f252f88653f9361d295c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"qiwzhang"}}