This is an automated email from the ASF dual-hosted git repository.
mgreber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push:
new 1a9862324 [webserver] Add auth principal to WebRequest
1a9862324 is described below
commit 1a98623244882434e9adefa57859e6fff575c2f5
Author: gabriellalotz <[email protected]>
AuthorDate: Thu Dec 19 11:44:13 2024 +0000
[webserver] Add auth principal to WebRequest
This patch updates the WebRequest structure to include the authenticated
principal. When SPNEGO is disabled, the authenticated principal defaults
to an empty string.
This enhancement is essential for REST API endpoints, allowing the
authenticated principal to be used for determining user permissions when
listing, creating, or deleting tables.
Change-Id: I8a64fb77cfa3bb83b911afc3ebaa8bd23e860663
Reviewed-on: http://gerrit.cloudera.org:8080/22242
Reviewed-by: Ashwani Raina <[email protected]>
Reviewed-by: Marton Greber <[email protected]>
Tested-by: Marton Greber <[email protected]>
---
src/kudu/server/webserver-test.cc | 64 +++++++++++++++++++++++++++++++++++
src/kudu/server/webserver.cc | 5 +++
src/kudu/util/web_callback_registry.h | 3 ++
3 files changed, 72 insertions(+)
diff --git a/src/kudu/server/webserver-test.cc
b/src/kudu/server/webserver-test.cc
index ee1c12efd..58ad4f171 100644
--- a/src/kudu/server/webserver-test.cc
+++ b/src/kudu/server/webserver-test.cc
@@ -27,6 +27,7 @@
#include <initializer_list>
#include <iosfwd>
#include <memory>
+#include <ostream>
#include <string>
#include <unordered_map>
#include <utility>
@@ -674,6 +675,69 @@ TEST_F(WebserverTest, TestPutMethodNotAllowed) {
ASSERT_EQ("Remote error: HTTP 401", s.ToString());
}
+// Test that authenticated principal is correctly passed to the handler.
+static void Handler(const Webserver::WebRequest& req,
Webserver::PrerenderedWebResponse* resp) {
+ resp->output << req.authn_principal;
+}
+
+class AuthnWebserverTest : public SpnegoWebserverTest {
+ protected:
+ void SetUp() override {
+ WebserverTest::SetUp();
+ server_->RegisterPrerenderedPathHandler(
+ "/authn", "AuthnWebserverTest", Handler, StyleMode::UNSTYLED, false);
+ }
+};
+
+class NoAuthnWebserverTest : public WebserverTest {
+ protected:
+ void SetUp() override {
+ WebserverTest::SetUp();
+ server_->RegisterPrerenderedPathHandler(
+ "/authn", "NoAuthnWebserverTest", Handler, StyleMode::UNSTYLED, false);
+ }
+};
+
+TEST_F(NoAuthnWebserverTest, TestUnauthenticatedUser) {
+ ASSERT_OK(curl_.FetchURL(Substitute("$0/authn", url_), &buf_));
+ ASSERT_EQ(buf_.ToString(), "");
+}
+
+// The following tests are skipped on macOS due to inconsistent behavior of
SPNEGO.
+// macOS heimdal kerberos caches the KDC port number, which can cause
subsequent tests to fail.
+// For more details, refer to KUDU-3533
(https://issues.apache.org/jira/browse/KUDU-3533)
+#ifndef __APPLE__
+
+TEST_F(AuthnWebserverTest, TestAuthenticatedUserPassedToHandler) {
+ ASSERT_OK(kdc_->Kinit("alice"));
+ curl_.set_auth(CurlAuthType::SPNEGO);
+ ASSERT_OK(curl_.FetchURL(Substitute("$0/authn", url_), &buf_));
+ ASSERT_STR_CONTAINS(buf_.ToString(), "[email protected]");
+}
+
+TEST_F(AuthnWebserverTest, TestUnauthenticatedBadKeytab) {
+ // Test based on the SpnegoWebserverTest::TestUnauthenticatedBadKeytab test.
+ ASSERT_OK(kdc_->Kinit("alice"));
+ ASSERT_OK(kdc_->RandomizePrincipalKey("HTTP/127.0.0.1"));
+ curl_.set_auth(CurlAuthType::SPNEGO);
+ Status s = curl_.FetchURL(Substitute("$0/authn", url_), &buf_);
+ EXPECT_EQ(s.ToString(), "Remote error: HTTP 401");
+ ASSERT_STR_MATCHES(buf_.ToString(),
+ "(Unspecified GSS failure|"
+ "GSSAPI Error: Miscellaneous failure|"
+ "Must authenticate with SPNEGO)");
+}
+
+TEST_F(AuthnWebserverTest, TestUnauthenticatedRequestWithoutClientAuth) {
+ // Test based on the SpnegoWebserverTest::TestUnauthenticatedNoClientAuth
test.
+ curl_.set_auth(CurlAuthType::SPNEGO);
+ Status curl_status = curl_.FetchURL(Substitute("$0/authn", url_), &buf_);
+ EXPECT_EQ("Remote error: HTTP 401", curl_status.ToString());
+ EXPECT_EQ("Must authenticate with SPNEGO.", buf_.ToString());
+}
+
+#endif
+
namespace {
// Handler that echoes back the path parameters and query parameters in
key-value pairs.
diff --git a/src/kudu/server/webserver.cc b/src/kudu/server/webserver.cc
index ecf15fc00..22f4cd1d0 100644
--- a/src/kudu/server/webserver.cc
+++ b/src/kudu/server/webserver.cc
@@ -670,6 +670,11 @@ sq_callback_result_t Webserver::RunPathHandler(
BuildArgumentMap(request_info->query_string, &req.parsed_args);
}
req.path_params = path_params;
+ if (request_info->remote_user != nullptr) {
+ req.authn_principal = request_info->remote_user;
+ } else {
+ req.authn_principal = "";
+ }
for (int i = 0; i < request_info->num_headers; i++) {
const auto& h = request_info->http_headers[i];
string key = h.name;
diff --git a/src/kudu/util/web_callback_registry.h
b/src/kudu/util/web_callback_registry.h
index 1d46bd8df..3d777a775 100644
--- a/src/kudu/util/web_callback_registry.h
+++ b/src/kudu/util/web_callback_registry.h
@@ -70,6 +70,9 @@ class WebCallbackRegistry {
// The HTTP request headers.
ArgumentMap request_headers;
+ // The authenticated principal, if any.
+ std::string authn_principal;
+
// The raw query string passed in the URL. May be empty.
std::string query_string;