From: Radoslaw Zarzynski Date: Wed, 11 Jan 2017 17:34:26 +0000 (+0100) Subject: rgw: remove the parts of auth framework that aren't necessary anymore. X-Git-Tag: v12.0.2~305^2~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=be9dabaf351edc8557061bb6941b95dbcf84c16c;p=ceph.git rgw: remove the parts of auth framework that aren't necessary anymore. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 250622df648d..8768a5343304 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -97,433 +97,12 @@ uint32_t rgw_perms_from_aclspec_default_strategy( } -/* RGWRemoteAuthApplier */ -uint32_t RGWRemoteAuthApplier::get_perms_from_aclspec(const aclspec_t& aclspec) const -{ - uint32_t perm = 0; - - /* For backward compatibility with ACLOwner. */ - perm |= rgw_perms_from_aclspec_default_strategy(info.acct_user, - aclspec); - - /* We also need to cover cases where rgw_keystone_implicit_tenants - * was enabled. */ - if (info.acct_user.tenant.empty()) { - const rgw_user tenanted_acct_user(info.acct_user.id, info.acct_user.id); - - perm |= rgw_perms_from_aclspec_default_strategy(tenanted_acct_user, - aclspec); - } - - /* Now it's a time for invoking additional strategy that was supplied by - * a specific auth engine. */ - if (extra_acl_strategy) { - perm |= extra_acl_strategy(aclspec); - } - - ldout(cct, 20) << "from ACL got perm=" << perm << dendl; - return perm; -} - -bool RGWRemoteAuthApplier::is_admin_of(const rgw_user& uid) const -{ - return info.is_admin; -} - -bool RGWRemoteAuthApplier::is_owner_of(const rgw_user& uid) const -{ - if (info.acct_user.tenant.empty()) { - const rgw_user tenanted_acct_user(info.acct_user.id, info.acct_user.id); - - if (tenanted_acct_user == uid) { - return true; - } - } - - return info.acct_user == uid; -} - -void RGWRemoteAuthApplier::to_str(std::ostream& out) const -{ - out << "RGWRemoteAuthApplier(acct_user=" << info.acct_user - << ", acct_name=" << info.acct_name - << ", perm_mask=" << info.perm_mask - << ", is_admin=" << info.is_admin << ")"; -} - -void RGWRemoteAuthApplier::create_account(const rgw_user& acct_user, - RGWUserInfo& user_info) const /* out */ -{ - rgw_user new_acct_user = acct_user; - - if (info.acct_type) { - //ldap/keystone for s3 users - user_info.type = info.acct_type; - } - - /* Administrator may enforce creating new accounts within their own tenants. - * The config parameter name is kept due to legacy. */ - if (new_acct_user.tenant.empty() && g_conf->rgw_keystone_implicit_tenants) { - new_acct_user.tenant = new_acct_user.id; - } - - user_info.user_id = new_acct_user; - user_info.display_name = info.acct_name; - - int ret = rgw_store_user_info(store, user_info, nullptr, nullptr, - real_time(), true); - if (ret < 0) { - ldout(cct, 0) << "ERROR: failed to store new user info: user=" - << user_info.user_id << " ret=" << ret << dendl; - throw ret; - } -} - -/* TODO(rzarzynski): we need to handle display_name changes. */ -void RGWRemoteAuthApplier::load_acct_info(RGWUserInfo& user_info) const /* out */ -{ - /* It's supposed that RGWRemoteAuthApplier tries to load account info - * that belongs to the authenticated identity. Another policy may be - * applied by using a RGWThirdPartyAccountAuthApplier decorator. */ - const rgw_user& acct_user = info.acct_user; - - /* Normally, empty "tenant" field of acct_user means the authenticated - * identity has the legacy, global tenant. However, due to inclusion - * of multi-tenancy, we got some special compatibility kludge for remote - * backends like Keystone. - * If the global tenant is the requested one, we try the same tenant as - * the user name first. If that RGWUserInfo exists, we use it. This way, - * migrated OpenStack users can get their namespaced containers and nobody's - * the wiser. - * If that fails, we look up in the requested (possibly empty) tenant. - * If that fails too, we create the account within the global or separated - * namespace depending on rgw_keystone_implicit_tenants. */ - if (acct_user.tenant.empty()) { - const rgw_user tenanted_uid(acct_user.id, acct_user.id); - - if (rgw_get_user_info_by_uid(store, tenanted_uid, user_info) >= 0) { - /* Succeeded. */ - return; - } - } - - if (rgw_get_user_info_by_uid(store, acct_user, user_info) < 0) { - ldout(cct, 0) << "NOTICE: couldn't map swift user " << acct_user << dendl; - create_account(acct_user, user_info); - } - - /* Succeeded if we are here (create_account() hasn't throwed). */ -} - - -/* LocalAuthApplier */ -/* static declaration */ -const std::string RGWLocalAuthApplier::NO_SUBUSER; - -uint32_t RGWLocalAuthApplier::get_perms_from_aclspec(const aclspec_t& aclspec) const -{ - return rgw_perms_from_aclspec_default_strategy(user_info.user_id, aclspec); -} - -bool RGWLocalAuthApplier::is_admin_of(const rgw_user& uid) const -{ - return user_info.admin || user_info.system; -} - -bool RGWLocalAuthApplier::is_owner_of(const rgw_user& uid) const -{ - return uid == user_info.user_id; -} - -void RGWLocalAuthApplier::to_str(std::ostream& out) const -{ - out << "RGWLocalAuthApplier(acct_user=" << user_info.user_id - << ", acct_name=" << user_info.display_name - << ", subuser=" << subuser - << ", perm_mask=" << get_perm_mask() - << ", is_admin=" << static_cast(user_info.admin) << ")"; -} - -uint32_t RGWLocalAuthApplier::get_perm_mask(const std::string& subuser_name, - const RGWUserInfo &uinfo) const -{ - if (!subuser_name.empty() && subuser_name != NO_SUBUSER) { - const auto iter = uinfo.subusers.find(subuser_name); - - if (iter != std::end(uinfo.subusers)) { - return iter->second.perm_mask; - } else { - /* Subuser specified but not found. */ - return RGW_PERM_NONE; - } - } else { - /* Due to backward compatibility. */ - return RGW_PERM_FULL_CONTROL; - } -} - -void RGWLocalAuthApplier::load_acct_info(RGWUserInfo& user_info) const /* out */ -{ - /* Load the account that belongs to the authenticated identity. An extra call - * to RADOS may be safely skipped in this case. */ - user_info = this->user_info; -} - - -RGWAuthApplier::aplptr_t RGWAnonymousAuthEngine::authenticate() const -{ - RGWUserInfo user_info; - rgw_get_anon_user(user_info); - - return apl_factory->create_apl_local(cct, user_info, - RGWLocalAuthApplier::NO_SUBUSER); -} - - -/* Keystone */ -bool RGWKeystoneAuthEngine::is_applicable() const noexcept -{ - if (! RGWTokenBasedAuthEngine::is_applicable()) { - return false; - } - - return ! cct->_conf->rgw_keystone_url.empty(); -} - -rgw::keystone::TokenEnvelope -RGWKeystoneAuthEngine::decode_pki_token(const std::string& token) const -{ - bufferlist token_body_bl; - int ret = rgw_decode_b64_cms(cct, token, token_body_bl); - if (ret < 0) { - ldout(cct, 20) << "cannot decode pki token" << dendl; - throw ret; - } else { - ldout(cct, 20) << "successfully decoded pki token" << dendl; - } - - rgw::keystone::TokenEnvelope token_body; - ret = token_body.parse(cct, token, token_body_bl, - rgw::keystone::CephCtxConfig::get_instance().get_api_version()); - if (ret < 0) { - throw ret; - } - - return token_body; -} - -rgw::keystone::TokenEnvelope -RGWKeystoneAuthEngine::get_from_keystone(const std::string& token) const -{ - using RGWValidateKeystoneToken - = rgw::keystone::Service::RGWValidateKeystoneToken; - - bufferlist token_body_bl; - RGWValidateKeystoneToken validate(cct, &token_body_bl); - - std::string url - = rgw::keystone::CephCtxConfig::get_instance().get_endpoint_url(); - if (url.empty()) { - throw -EINVAL; - } - - const auto keystone_version = rgw::keystone::CephCtxConfig::get_instance().get_api_version(); - if (keystone_version == rgw::keystone::ApiVersion::VER_2) { - url.append("v2.0/tokens/" + token); - } else if (keystone_version == rgw::keystone::ApiVersion::VER_3) { - url.append("v3/auth/tokens"); - validate.append_header("X-Subject-Token", token); - } - - std::string admin_token; - if (rgw::keystone::Service::get_admin_token( - cct, - rgw::keystone::TokenCache::get_instance(), - rgw::keystone::CephCtxConfig::get_instance(), - admin_token) < 0) { - throw -EINVAL; - } - - validate.append_header("X-Auth-Token", admin_token); - validate.set_send_length(0); - - int ret = validate.process(url.c_str()); - if (ret < 0) { - throw ret; - } - - /* NULL terminate for debug output. */ - token_body_bl.append(static_cast(0)); - ldout(cct, 20) << "received response status=" << validate.get_http_status() - << ", body=" << token_body_bl.c_str() << dendl; - - /* Detect Keystone rejection earlier than during the token parsing. - * Although failure at the parsing phase doesn't impose a threat, - * this allows to return proper error code (EACCESS instead of EINVAL - * or similar) and thus improves logging. */ - if (validate.get_http_status() == - /* Most likely: wrong admin credentials or admin token. */ - RGWValidateKeystoneToken::HTTP_STATUS_UNAUTHORIZED || - validate.get_http_status() == - /* Most likely: non-existent token supplied by the client. */ - RGWValidateKeystoneToken::HTTP_STATUS_NOTFOUND) { - throw -EACCES; - } - - rgw::keystone::TokenEnvelope token_body; - ret = token_body.parse(cct, token, token_body_bl, keystone_version); - if (ret < 0) { - throw ret; - } - - return token_body; -} - -RGWRemoteAuthApplier::AuthInfo -RGWKeystoneAuthEngine::get_creds_info(const rgw::keystone::TokenEnvelope& token, - const std::vector& admin_roles - ) const noexcept -{ - using acct_privilege_t = RGWRemoteAuthApplier::AuthInfo::acct_privilege_t; - - /* Check whether the user has an admin status. */ - acct_privilege_t level = acct_privilege_t::IS_PLAIN_ACCT; - for (const auto& admin_role : admin_roles) { - if (token.has_role(admin_role)) { - level = acct_privilege_t::IS_ADMIN_ACCT; - break; - } - } - - return RGWRemoteAuthApplier::AuthInfo { - /* Suggested account name for the authenticated user. */ - rgw_user(token.get_project_id()), - /* User's display name (aka real name). */ - token.get_project_name(), - /* Keystone doesn't support RGW's subuser concept, so we cannot cut down - * the access rights through the perm_mask. At least at this layer. */ - RGW_PERM_FULL_CONTROL, - level, - }; -} - static inline const std::string make_spec_item(const std::string& tenant, const std::string& id) { return tenant + ":" + id; } -RGWKeystoneAuthEngine::acl_strategy_t -RGWKeystoneAuthEngine::get_acl_strategy(const rgw::keystone::TokenEnvelope& token) const -{ - /* The primary identity is constructed upon UUIDs. */ - const auto& tenant_uuid = token.get_project_id(); - const auto& user_uuid = token.get_user_id(); - - /* For Keystone v2 an alias may be also used. */ - const auto& tenant_name = token.get_project_name(); - const auto& user_name = token.get_user_name(); - - /* Construct all possible combinations including Swift's wildcards. */ - const std::array allowed_items = { - make_spec_item(tenant_uuid, user_uuid), - make_spec_item(tenant_name, user_name), - - /* Wildcards. */ - make_spec_item(tenant_uuid, "*"), - make_spec_item(tenant_name, "*"), - make_spec_item("*", user_uuid), - make_spec_item("*", user_name), - }; - - /* Lambda will obtain a copy of (not a reference to!) allowed_items. */ - return [allowed_items](const RGWIdentityApplier::aclspec_t& aclspec) { - uint32_t perm = 0; - - for (const auto& allowed_item : allowed_items) { - const auto iter = aclspec.find(allowed_item); - - if (std::end(aclspec) != iter) { - perm |= iter->second; - } - } - - return perm; - }; -} - -RGWAuthApplier::aplptr_t RGWKeystoneAuthEngine::authenticate() const -{ - rgw::keystone::TokenEnvelope t; - - /* This will be initialized on the first call to this method. In C++11 it's - * also thread-safe. */ - static struct RolesCacher { - RolesCacher(CephContext * const cct) { - get_str_vec(cct->_conf->rgw_keystone_accepted_roles, plain); - get_str_vec(cct->_conf->rgw_keystone_accepted_admin_roles, admin); - - /* Let's suppose that having an admin role implies also a regular one. */ - plain.insert(std::end(plain), std::begin(admin), std::end(admin)); - } - - std::vector plain; - std::vector admin; - } roles(cct); - - /* Token ID is a concept that makes dealing with PKI tokens more effective. - * Instead of storing several kilobytes, a short hash can be burried. */ - const auto& token_id = rgw_get_token_id(token); - ldout(cct, 20) << "token_id=" << token_id << dendl; - - /* Check cache first. */ - if (rgw::keystone::TokenCache::get_instance().find(token_id, t)) { - ldout(cct, 20) << "cached token.project.id=" << t.get_project_id() - << dendl; - return apl_factory->create_apl_remote(cct, - get_acl_strategy(t), - get_creds_info(t, roles.admin)); - } - - /* Retrieve token. */ - if (rgw_is_pki_token(token)) { - try { - t = decode_pki_token(token); - } catch (...) { - /* Last resort. */ - t = get_from_keystone(token); - } - } else { - /* Can't decode, just go to the Keystone server for validation. */ - t = get_from_keystone(token); - } - - /* Verify expiration. */ - if (t.expired()) { - ldout(cct, 0) << "got expired token: " << t.get_project_name() - << ":" << t.get_user_name() - << " expired: " << t.get_expires() << dendl; - return nullptr; - } - - /* Check for necessary roles. */ - for (const auto& role : roles.plain) { - if (t.has_role(role) == true) { - ldout(cct, 0) << "validated token: " << t.get_project_name() - << ":" << t.get_user_name() - << " expires: " << t.get_expires() << dendl; - rgw::keystone::TokenCache::get_instance().add(token_id, t); - return apl_factory->create_apl_remote(cct, - get_acl_strategy(t), - get_creds_info(t, roles.admin)); - } - } - - ldout(cct, 0) << "user does not hold a matching role; required roles: " - << g_conf->rgw_keystone_accepted_roles << dendl; - - return nullptr; -} rgw::auth::Engine::result_t rgw::auth::Strategy::authenticate(const req_state* const s) const diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index 2abf97e2e8e7..ca7ce6fafd4a 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -17,339 +17,6 @@ #define RGW_USER_ANON_ID "anonymous" -/* Load information about identity that will be used by RGWOp to authorize - * any operation that comes from an authenticated user. */ -class RGWIdentityApplier { -public: - typedef std::map aclspec_t; - - virtual ~RGWIdentityApplier() {}; - - /* Translate the ACL provided in @aclspec into concrete permission set that - * can be used in authorization phase (particularly in verify_permission - * method of a given RGWOp). - * - * XXX: implementation is responsible for giving the real semantic to the - * items in @aclspec. That is, their meaning may depend on particular auth - * engine that was used. */ - virtual uint32_t get_perms_from_aclspec(const aclspec_t& aclspec) const = 0; - - /* Verify whether a given identity *can be treated as* an admin of - * the rgw_user (account in Swift's terminology) specified in @uid. */ - virtual bool is_admin_of(const rgw_user& uid) const = 0; - - /* Verify whether a given identity *is* the owner of the rgw_user - * (account in Swift's terminology) specified in @uid. */ - virtual bool is_owner_of(const rgw_user& uid) const = 0; - - /* Return the permission mask that is used to narrow down the set of - * operations allowed for a given identity. This method reflects the idea - * of subuser tied to RGWUserInfo. */ - virtual uint32_t get_perm_mask() const = 0; - - virtual bool is_anonymous() const final { - /* If the identity owns the anonymous account (rgw_user), it's considered - * the anonymous identity. */ - return is_owner_of(rgw_user(RGW_USER_ANON_ID)); - } - - virtual void to_str(std::ostream& out) const = 0; -}; - -inline std::ostream& operator<<(std::ostream& out, - const RGWIdentityApplier &id) { - id.to_str(out); - return out; -} - -uint32_t rgw_perms_from_aclspec_default_strategy( - const rgw_user& uid, - const RGWIdentityApplier::aclspec_t& aclspec); - - -/* Interface for classes applying changes to request state/RADOS store imposed - * by a particular RGWAuthEngine. - * - * Implementations must also conform to RGWIdentityApplier interface to apply - * authorization policy (ACLs, account's ownership and entitlement). - * - * In contrast to RGWAuthEngine, implementations of this interface are allowed - * to handle req_state or RGWRados in the read-write manner. */ -class RGWAuthApplier : public RGWIdentityApplier { - template friend class RGWDecoratingAuthApplier; - -protected: - CephContext * const cct; - -public: - typedef std::unique_ptr aplptr_t; - - RGWAuthApplier(CephContext * const cct) : cct(cct) {} - ~RGWAuthApplier() override {}; - - /* Fill provided RGWUserInfo with information about the account that - * RGWOp will operate on. Errors are handled solely through exceptions. - * - * XXX: be aware that the "account" term refers to rgw_user. The naming - * is legacy. */ - virtual void load_acct_info(RGWUserInfo& user_info) const = 0; /* out */ - - /* Apply any changes to request state. This method will be most useful for - * TempURL of Swift API or AWSv4. */ - virtual void modify_request_state(req_state * s) const {} /* in/out */ -}; - - -/* RGWRemoteAuthApplier targets those authentication engines which don't need - * to ask the RADOS store while performing the auth process. Instead, they - * obtain credentials from an external source like Keystone or LDAP. - * - * As the authenticated user may not have an account yet, RGWRemoteAuthApplier - * must be able to create it basing on data passed by an auth engine. Those - * data will be used to fill RGWUserInfo structure. */ -class RGWRemoteAuthApplier : public RGWAuthApplier { -public: - class AuthInfo { - friend class RGWRemoteAuthApplier; - protected: - const rgw_user acct_user; - const std::string acct_name; - const uint32_t perm_mask; - const bool is_admin; - const uint32_t acct_type; - - public: - enum class acct_privilege_t { - IS_ADMIN_ACCT, - IS_PLAIN_ACCT - }; - - AuthInfo(const rgw_user& acct_user, - const std::string& acct_name, - const uint32_t perm_mask, - const acct_privilege_t level, - const uint32_t acct_type=TYPE_NONE) - : acct_user(acct_user), - acct_name(acct_name), - perm_mask(perm_mask), - is_admin(acct_privilege_t::IS_ADMIN_ACCT == level), - acct_type(acct_type) { - } - }; - - using aclspec_t = rgw::auth::Identity::aclspec_t; - typedef std::function acl_strategy_t; - -protected: - /* Read-write is intensional here due to RGWUserInfo creation process. */ - RGWRados * const store; - - /* Supplemental strategy for extracting permissions from ACLs. Its results - * will be combined (ORed) with a default strategy that is responsible for - * handling backward compatibility. */ - const acl_strategy_t extra_acl_strategy; - - const AuthInfo info; - - virtual void create_account(const rgw_user& acct_user, - RGWUserInfo& user_info) const; /* out */ - -public: - RGWRemoteAuthApplier(CephContext * const cct, - RGWRados * const store, - acl_strategy_t&& extra_acl_strategy, - const AuthInfo& info) - : RGWAuthApplier(cct), - store(store), - extra_acl_strategy(std::move(extra_acl_strategy)), - info(info) { - } - - uint32_t get_perms_from_aclspec(const aclspec_t& aclspec) const override; - bool is_admin_of(const rgw_user& uid) const override; - bool is_owner_of(const rgw_user& uid) const override; - uint32_t get_perm_mask() const override { return info.perm_mask; } - void to_str(std::ostream& out) const override; - void load_acct_info(RGWUserInfo& user_info) const override; /* out */ - - struct Factory { - virtual ~Factory() {} - /* Providing r-value reference here is required intensionally. Callee is - * thus disallowed to handle std::function in a way that could inhibit - * the move behaviour (like forgetting about std::moving a l-value). */ - virtual aplptr_t create_apl_remote(CephContext * const cct, - acl_strategy_t&& extra_acl_strategy, - const AuthInfo info) const = 0; - }; -}; - - -/* Local auth applier targets those auth engines that store user information - * in the RADOS store. As a consequence of performing the authentication, they - * will have the RGWUserInfo structure loaded. Exploiting this trait allows to - * avoid additional call to underlying RADOS store. */ -class RGWLocalAuthApplier : public RGWAuthApplier { -protected: - const RGWUserInfo user_info; - const std::string subuser; - - uint32_t get_perm_mask(const std::string& subuser_name, - const RGWUserInfo &uinfo) const; - -public: - static const std::string NO_SUBUSER; - - RGWLocalAuthApplier(CephContext * const cct, - const RGWUserInfo& user_info, - const std::string subuser) - : RGWAuthApplier(cct), - user_info(user_info), - subuser(subuser) { - } - - - uint32_t get_perms_from_aclspec(const aclspec_t& aclspec) const override; - bool is_admin_of(const rgw_user& uid) const override; - bool is_owner_of(const rgw_user& uid) const override; - uint32_t get_perm_mask() const override { - return get_perm_mask(subuser, user_info); - } - void to_str(std::ostream& out) const override; - void load_acct_info(RGWUserInfo& user_info) const override; /* out */ - - struct Factory { - virtual ~Factory() {} - virtual aplptr_t create_apl_local(CephContext * const cct, - const RGWUserInfo& user_info, - const std::string& subuser) const = 0; - }; -}; - - -/* Abstract class for authentication backends (auth engines) in RadosGW. - * - * An engine is supposed only to: - * - authenticate (not authorize!) a given request basing on req_state, - * - provide an upper layer with RGWAuthApplier to commit all changes to - * data structures (like req_state) and to the RADOS store (creating - * an account, synchronizing user personal info). - * Auth engine MUST NOT make any changes to req_state nor RADOS store. - * - * Separation between authentication and global state modification has been - * introduced because many auth engines are perfectly orthogonal to applier - * and thus they can be decoupled. Additional motivation is clearly distinguish - * all places which can modify underlying data structures. */ -class RGWAuthEngine { -protected: - CephContext * const cct; - - RGWAuthEngine(CephContext * const cct) - : cct(cct) { - } - /* Make the engines non-copyable and non-moveable due to const-correctness - * and aggregating applier factories less costly and error-prone. */ - RGWAuthEngine(const RGWAuthEngine&) = delete; - RGWAuthEngine& operator=(const RGWAuthEngine&) = delete; - -public: - /* Get name of the auth engine. */ - virtual const char* get_name() const noexcept = 0; - - /* Fast, non-throwing method for screening whether a concrete engine may - * be interested in handling a specific request. */ - virtual bool is_applicable() const noexcept = 0; - - /* Throwing method for identity verification. When the check is positive - * an implementation should return RGWAuthApplier::aplptr_t containing - * a non-null pointer to object conforming the RGWAuthApplier interface. - * Otherwise, the authentication is treated as failed. - * An error may be signalised by throwing an exception of int type with - * errno value inside. Those value are always negative. */ - virtual RGWAuthApplier::aplptr_t authenticate() const = 0; - - virtual ~RGWAuthEngine() {}; -}; - - -/* Abstract base class for all token-based auth engines. */ -class RGWTokenBasedAuthEngine : public RGWAuthEngine { -protected: - const std::string token; - -public: - class Extractor { - public: - virtual ~Extractor() {}; - virtual std::string get_token() const = 0; - }; - - RGWTokenBasedAuthEngine(CephContext * const cct, - const Extractor& extr) - : RGWAuthEngine(cct), - token(extr.get_token()) { - } - - bool is_applicable() const noexcept override { - return !token.empty(); - } -}; - -/* Keystone. */ -class RGWKeystoneAuthEngine : public RGWTokenBasedAuthEngine { -protected: - using acl_strategy_t = RGWRemoteAuthApplier::acl_strategy_t; - using token_envelope_t = rgw::keystone::TokenEnvelope; - - const RGWRemoteAuthApplier::Factory * const apl_factory; - - /* Helper methods. */ - token_envelope_t decode_pki_token(const std::string& token) const; - token_envelope_t get_from_keystone(const std::string& token) const; - acl_strategy_t get_acl_strategy(const token_envelope_t& token) const; - RGWRemoteAuthApplier::AuthInfo get_creds_info(const token_envelope_t& token, - const std::vector& admin_roles - ) const noexcept; -public: - RGWKeystoneAuthEngine(CephContext * const cct, - const Extractor& extr, - const RGWRemoteAuthApplier::Factory * const apl_factory) - : RGWTokenBasedAuthEngine(cct, extr), - apl_factory(apl_factory) { - } - - const char* get_name() const noexcept override { - return "RGWKeystoneAuthEngine"; - } - - bool is_applicable() const noexcept override; - RGWAuthApplier::aplptr_t authenticate() const override; -}; - - -/* Anonymous */ -class RGWAnonymousAuthEngine : public RGWTokenBasedAuthEngine { - const RGWLocalAuthApplier::Factory * const apl_factory; - -public: - RGWAnonymousAuthEngine(CephContext * const cct, - const Extractor& extr, - const RGWLocalAuthApplier::Factory * const apl_factory) - : RGWTokenBasedAuthEngine(cct, extr), - apl_factory(apl_factory) { - } - - bool is_applicable() const noexcept override { - return token.empty(); - } - - const char* get_name() const noexcept override { - return "RGWAnonymousAuthEngine"; - } - - RGWAuthApplier::aplptr_t authenticate() const override; -}; - - namespace rgw { namespace auth {