Skip to content

Commit

Permalink
utils: Added new methods to request_auth
Browse files Browse the repository at this point in the history
Added accessors for user type and whether or not authentication was
successful.  Also added new exception to thrown if authentication fails,
but username is known.

Also added a flag to indicate if auth was enabled.  Needed for auditing.

Signed-off-by: Michael Boquard <michael@redpanda.com>
  • Loading branch information
michael-redpanda committed Oct 25, 2023
1 parent f4554a3 commit 47f3ecc
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
20 changes: 12 additions & 8 deletions src/v/utils/request_auth.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ request_authenticator::authenticate(const ss::http::request& req) {
// a unit test or a standalone pandaproxy/schema_registry
return request_auth_result(
request_auth_result::authenticated::yes,
request_auth_result::superuser::yes);
request_auth_result::superuser::yes,
request_auth_result::auth_required::no);
}

const auto& cred_store = _controller->get_credential_store().local();
Expand All @@ -62,7 +63,8 @@ request_authenticator::authenticate(const ss::http::request& req) {
// treat them as anonymous.
return request_auth_result(
request_auth_result::authenticated::yes,
request_auth_result::superuser::yes);
request_auth_result::superuser::yes,
request_auth_result::auth_required::no);
}
} else {
throw;
Expand Down Expand Up @@ -111,8 +113,8 @@ request_auth_result request_authenticator::do_authenticate(
logger.warn,
"Client auth failure: user '{}' not found",
username);
throw ss::httpd::base_exception(
"Unauthorized", ss::http::reply::status_type::unauthorized);
throw unauthorized_user_exception(
std::move(username), "Unauthorized");
} else {
const auto& cred = cred_opt.value();
ss::sstring sasl_mechanism;
Expand All @@ -138,8 +140,8 @@ request_auth_result request_authenticator::do_authenticate(
logger.warn,
"Client auth failure: user '{}' wrong password",
username);
throw ss::httpd::base_exception(
"Unauthorized", ss::http::reply::status_type::unauthorized);
throw unauthorized_user_exception(
std::move(username), "Unauthorized");
} else {
vlog(logger.trace, "Authenticated user {}", username);
const auto& superusers = _superusers();
Expand All @@ -161,11 +163,13 @@ request_auth_result request_authenticator::do_authenticate(
if (require_auth) {
return request_auth_result(
request_auth_result::authenticated::no,
request_auth_result::superuser::no);
request_auth_result::superuser::no,
request_auth_result::auth_required::yes);
} else {
return request_auth_result(
request_auth_result::authenticated::yes,
request_auth_result::superuser::yes);
request_auth_result::superuser::yes,
request_auth_result::auth_required::no);
}
}
}
Expand Down
31 changes: 28 additions & 3 deletions src/v/utils/request_auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,22 @@
#include "security/fwd.h"
#include "security/types.h"

#include <seastar/http/exception.hh>
#include <seastar/http/request.hh>

class unauthorized_user_exception : public ss::httpd::base_exception {
public:
unauthorized_user_exception(
security::credential_user username, const std::string& msg)
: ss::httpd::base_exception(
msg, ss::http::reply::status_type::unauthorized)
, _username(std::move(username)) {}
const security::credential_user& get_username() const { return _username; }

private:
security::credential_user _username;
};

/**
* Helper for HTTP request handlers that would like to enforce
* authentication and authorization rules.
Expand All @@ -32,6 +46,7 @@ class [[nodiscard]] request_auth_result {
public:
using authenticated = ss::bool_class<struct authenticated_tag>;
using superuser = ss::bool_class<struct superuser_tag>;
using auth_required = ss::bool_class<struct auth_required_tag>;

/**
* Authenticated user. They have passed authentication so we know
Expand All @@ -49,16 +64,21 @@ class [[nodiscard]] request_auth_result {
, _password(std::move(password))
, _sasl_mechanism(std::move(sasl_mechanism))
, _authenticated(true)
, _superuser(is_superuser){};
, _superuser(is_superuser)
, _auth_required(true){};

/**
* Anonymous user. They may still be considered authenticated/superuser
* if the global require_auth property is set to false (i.e. anonymous
* users have all powers)
*/
request_auth_result(authenticated is_authenticated, superuser is_superuser)
request_auth_result(
authenticated is_authenticated,
superuser is_superuser,
auth_required is_auth_required)
: _authenticated(is_authenticated)
, _superuser(is_superuser){};
, _superuser(is_superuser)
, _auth_required(is_auth_required){};

~request_auth_result() noexcept(false);

Expand All @@ -81,12 +101,17 @@ class [[nodiscard]] request_auth_result {
ss::sstring const& get_password() const { return _password; }
ss::sstring const& get_sasl_mechanism() const { return _sasl_mechanism; }

bool is_authenticated() const { return _authenticated; };
bool is_superuser() const { return _superuser; }
bool is_auth_required() const { return _auth_required; }

private:
security::credential_user _username;
security::credential_password _password;
ss::sstring _sasl_mechanism;
bool _authenticated{false};
bool _superuser{false};
bool _auth_required{false};
bool _checked{false};
};

Expand Down

0 comments on commit 47f3ecc

Please sign in to comment.