Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions src/envoy/http/authn/origin_authenticator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "absl/strings/match.h"
#include "authentication/v1alpha1/policy.pb.h"
#include "common/http/headers.h"
#include "common/http/utility.h"
#include "src/envoy/http/authn/authn_utils.h"

using istio::authn::Payload;
Expand Down Expand Up @@ -64,11 +65,16 @@ bool OriginAuthenticator::run(Payload* payload) {
return true;
}

absl::string_view request_path;
absl::string_view path;
if (filter_context()->headerMap().Path() != nullptr) {
request_path =
filter_context()->headerMap().Path()->value().getStringView();
ENVOY_LOG(debug, "Got request path {}", request_path);
path = filter_context()->headerMap().Path()->value().getStringView();

// Trim query parameters and/or fragment if present
size_t offset = path.find_first_of("?#");
if (offset != absl::string_view::npos) {
path.remove_suffix(path.length() - offset);
}
ENVOY_LOG(trace, "Got request path {}", path);
} else {
ENVOY_LOG(error,
"Failed to get request path, JWT will always be used for "
Expand All @@ -80,8 +86,8 @@ bool OriginAuthenticator::run(Payload* payload) {
for (const auto& method : policy_.origins()) {
const auto& jwt = method.jwt();

if (AuthnUtils::ShouldValidateJwtPerPath(request_path, jwt)) {
ENVOY_LOG(debug, "Validating request path {} for jwt {}", request_path,
if (AuthnUtils::ShouldValidateJwtPerPath(path, jwt)) {
ENVOY_LOG(debug, "Validating request path {} for jwt {}", path,
jwt.DebugString());
// set triggered to true if any of the jwt trigger rule matched.
triggered = true;
Expand Down
63 changes: 61 additions & 2 deletions src/envoy/http/authn/origin_authenticator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ const char kSingleOriginMethodWithTriggerRulePolicy[] = R"(
}
)";

const char kSingleOriginMethodWithExcludeTriggerRulePolicy[] = R"(
principal_binding: USE_ORIGIN
origins {
jwt {
issuer: "abc.xyz"
trigger_rules: {
excluded_paths: {
exact: "/login"
}
}
}
}
)";

const char kMultipleOriginMethodWithTriggerRulePolicy[] = R"(
principal_binding: USE_ORIGIN
origins {
Expand Down Expand Up @@ -327,15 +341,60 @@ TEST_P(OriginAuthenticatorTest, SingleRuleTriggered) {
filter_context_.authenticationResult()));
}

TEST_P(OriginAuthenticatorTest, SingleRuleTriggeredWithComponents) {
const std::vector<std::string> input_paths{"/allow?",
"/allow?a=b&c=d",
"/allow??",
"/allow??",
"/allow?#",
"/allow#?",
"/allow#a",
"/allow#$"
"/allow?a=b#c",
"/allow#a?b=c"};
for (const auto& path : input_paths) {
ASSERT_TRUE(Protobuf::TextFormat::ParseFromString(
kSingleOriginMethodWithTriggerRulePolicy, &policy_));

createAuthenticator();

EXPECT_CALL(*authenticator_, validateJwt(_, _))
.Times(1)
.WillOnce(DoAll(SetArgPointee<1>(jwt_payload_), Return(true)));

setPath(path);
EXPECT_TRUE(authenticator_->run(payload_));
EXPECT_TRUE(TestUtility::protoEqual(
expected_result_when_pass_, filter_context_.authenticationResult()));
}
}

TEST_P(OriginAuthenticatorTest, SingleRuleNotTriggered) {
const std::vector<std::string> input_paths{"/bad", "/allow$?", "/allow$#"};
for (const auto& path : input_paths) {
ASSERT_TRUE(Protobuf::TextFormat::ParseFromString(
kSingleOriginMethodWithTriggerRulePolicy, &policy_));

createAuthenticator();

EXPECT_CALL(*authenticator_, validateJwt(_, _)).Times(0);

setPath(path);
EXPECT_TRUE(authenticator_->run(payload_));
EXPECT_TRUE(TestUtility::protoEqual(
initial_result_, filter_context_.authenticationResult()));
}
}

TEST_P(OriginAuthenticatorTest, SingleExcludeRuleTriggeredWithQueryParam) {
ASSERT_TRUE(Protobuf::TextFormat::ParseFromString(
kSingleOriginMethodWithTriggerRulePolicy, &policy_));
kSingleOriginMethodWithExcludeTriggerRulePolicy, &policy_));

createAuthenticator();

EXPECT_CALL(*authenticator_, validateJwt(_, _)).Times(0);

setPath("/bad");
setPath("/login?a=b&c=d");
EXPECT_TRUE(authenticator_->run(payload_));
EXPECT_TRUE(TestUtility::protoEqual(initial_result_,
filter_context_.authenticationResult()));
Expand Down