From: Radoslaw Zarzynski Date: Tue, 7 Feb 2017 14:11:19 +0000 (+0100) Subject: rgw: RGWPostObj_ObjStore_S3 doesn't instantiate auth strategy for each request anymore. X-Git-Tag: v12.0.2~305^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f13f04bbb320e4d428c1720ba43f0e6a2899208d;p=ceph.git rgw: RGWPostObj_ObjStore_S3 doesn't instantiate auth strategy for each request anymore. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index a50229cb3670..f52cc7752da7 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -71,12 +71,18 @@ public: }; +template class AWSv2AuthStrategy : public rgw::auth::Strategy, public rgw::auth::LocalApplier::Factory { typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t; + + static_assert(std::is_base_of::value, + "ExtractorT must be a subclass of rgw::auth::s3::ExtractorT"); + RGWRados* const store; + ExtractorT extractor; - rgw::auth::s3::RGWS3V2Extractor extractor; ExternalAuthStrategy external_engines; LocalVersion2ndEngine local_engine; @@ -99,23 +105,9 @@ public: local_engine(cct, store, extractor, static_cast(this)) { add_engine(Control::SUFFICIENT, external_engines); - if (cct->_conf->rgw_s3_auth_use_rados) { - add_engine(Control::SUFFICIENT, local_engine); - } - } - /* FIXME(rzarzynski): hack for S3's browsers upload. */ - AWSv2AuthStrategy(CephContext* const cct, - RGWRados* const store, - Version2ndEngine::Extractor* const external_extractor) - : store(store), - extractor(cct), - external_engines(cct, store, external_extractor), - local_engine(cct, store, *external_extractor, - static_cast(this)) { - add_engine(Control::SUFFICIENT, external_engines); if (cct->_conf->rgw_s3_auth_use_rados) { - add_engine(Control::SUFFICIENT, local_engine); + add_engine(Control::FALLBACK, local_engine); } } diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 820efc2307d3..e01858e9764b 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1334,10 +1334,16 @@ struct req_state; class RGWEnv; +/* Namespaced forward declarations. */ namespace rgw { -namespace io { -class BasicClient; -} + namespace auth { + namespace s3 { + class RGWGetPolicyV2Extractor; + } + } + namespace io { + class BasicClient; + } } struct req_info { @@ -1735,6 +1741,21 @@ struct req_state { std::unique_ptr identity; std::unique_ptr completer; + + /* A container for credentials of the S3's browser upload. It's necessary + * because: 1) the ::authenticate() method of auth engines and strategies + * take req_state only; 2) auth strategies live much longer than RGWOps - + * there is no way to pass additional data dependencies through ctors. */ + class { + /* Writer. */ + friend class RGWPostObj_ObjStore_S3; + /* Reader. */ + friend class rgw::auth::s3::RGWGetPolicyV2Extractor; + + std::string access_key; + std::string signature; + ceph::bufferlist encoded_policy; + } s3_postobj_creds; } auth; std::unique_ptr user_acl; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 63bd0b99cdda..5d18249e2f86 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1798,39 +1798,28 @@ int RGWPostObj_ObjStore_S3::get_params() return 0; } -static std::string to_string(ceph::bufferlist& bl) -{ - return std::string(bl.c_str(), - static_cast(bl.length())); -} - int RGWPostObj_ObjStore_S3::get_policy() { - bufferlist encoded_policy; - - if (part_bl("policy", &encoded_policy)) { + if (part_bl("policy", &s->auth.s3_postobj_creds.encoded_policy)) { // check that the signature matches the encoded policy - string s3_access_key; - if (!part_str("AWSAccessKeyId", &s3_access_key)) { + if (! part_str("AWSAccessKeyId", &s->auth.s3_postobj_creds.access_key)) { ldout(s->cct, 0) << "No S3 access key found!" << dendl; err_msg = "Missing access key"; return -EINVAL; } string received_signature_str; - if (!part_str("signature", &received_signature_str)) { + if (! part_str("signature", &s->auth.s3_postobj_creds.signature)) { ldout(s->cct, 0) << "No signature found!" << dendl; err_msg = "Missing signature"; return -EINVAL; } - rgw::auth::s3::RGWGetPolicyV2Extractor extr(s3_access_key, - received_signature_str, - to_string(encoded_policy)); - /* FIXME: this is a makeshift solution. The browser upload authenication will be + /* FIXME: this is a makeshift solution. The browser upload authentication will be * handled by an instance of rgw::auth::Completer spawned in Handler's authorize() - * method. Thus creating a strategy per request won't be necessary. */ - const rgw::auth::s3::AWSv2AuthStrategy strategy(g_ceph_context, store, &extr); + * method. */ + static const rgw::auth::s3::AWSv2AuthStrategy< + rgw::auth::s3::RGWGetPolicyV2Extractor> strategy(g_ceph_context, store); try { auto result = strategy.authenticate(s); if (result.get_status() != decltype(result)::Status::GRANTED) { @@ -1859,7 +1848,7 @@ int RGWPostObj_ObjStore_S3::get_policy() ceph::bufferlist decoded_policy; try { - decoded_policy.decode_base64(encoded_policy); + decoded_policy.decode_base64(s->auth.s3_postobj_creds.encoded_policy); } catch (buffer::error& err) { ldout(s->cct, 0) << "failed to decode_base64 policy" << dendl; err_msg = "Could not decode policy"; @@ -3896,7 +3885,7 @@ int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s) { /* TODO(rzarzynski): this will be moved to the S3 handlers -- in exactly * way like we currently have in the case of Swift API. */ - static const rgw::auth::s3::AWSv2AuthStrategy strategy(g_ceph_context, store); + static const rgw::auth::s3::AWSv2AuthStrategy strategy(g_ceph_context, store); try { auto result = strategy.authenticate(s); if (result.get_status() != decltype(result)::Status::GRANTED) { diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 6ca8c899a6d3..dcd9311d18c4 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -685,25 +685,22 @@ public: class RGWGetPolicyV2Extractor : public Version2ndEngine::Extractor { -private: - std::string access_key_id; - std::string signature; - std::string string_to_sign; + static std::string to_string(ceph::bufferlist bl) { + return std::string(bl.c_str(), + static_cast(bl.length())); + } public: - RGWGetPolicyV2Extractor(std::string access_key_id, - std::string signature, - std::string string_to_sign) - : access_key_id(std::move(access_key_id)), - signature(std::move(signature)), - string_to_sign(std::move(string_to_sign)) { + RGWGetPolicyV2Extractor(CephContext*) { } std::tuple get_auth_data(const req_state* s) const override { - return std::make_tuple(access_key_id, signature, string_to_sign); + return std::make_tuple(s->auth.s3_postobj_creds.access_key, + s->auth.s3_postobj_creds.signature, + to_string(s->auth.s3_postobj_creds.encoded_policy)); } };