mirror of
https://github.com/ceph/ceph
synced 2025-01-04 10:12:30 +00:00
rgw: RGWPostObj_ObjStore_S3 doesn't instantiate auth strategy for each request anymore.
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
This commit is contained in:
parent
1ad1d83997
commit
f13f04bbb3
@ -71,12 +71,18 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <class ExtractorT>
|
||||
class AWSv2AuthStrategy : public rgw::auth::Strategy,
|
||||
public rgw::auth::LocalApplier::Factory {
|
||||
typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
|
||||
RGWRados* const store;
|
||||
|
||||
rgw::auth::s3::RGWS3V2Extractor extractor;
|
||||
static_assert(std::is_base_of<rgw::auth::s3::Version2ndEngine::Extractor,
|
||||
ExtractorT>::value,
|
||||
"ExtractorT must be a subclass of rgw::auth::s3::ExtractorT");
|
||||
|
||||
RGWRados* const store;
|
||||
ExtractorT extractor;
|
||||
|
||||
ExternalAuthStrategy external_engines;
|
||||
LocalVersion2ndEngine local_engine;
|
||||
|
||||
@ -99,23 +105,9 @@ public:
|
||||
local_engine(cct, store, extractor,
|
||||
static_cast<rgw::auth::LocalApplier::Factory*>(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<rgw::auth::LocalApplier::Factory*>(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1334,13 @@ struct req_state;
|
||||
|
||||
class RGWEnv;
|
||||
|
||||
/* Namespaced forward declarations. */
|
||||
namespace rgw {
|
||||
namespace auth {
|
||||
namespace s3 {
|
||||
class RGWGetPolicyV2Extractor;
|
||||
}
|
||||
}
|
||||
namespace io {
|
||||
class BasicClient;
|
||||
}
|
||||
@ -1735,6 +1741,21 @@ struct req_state {
|
||||
std::unique_ptr<rgw::auth::Identity> identity;
|
||||
|
||||
std::unique_ptr<rgw::auth::Completer> 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<RGWAccessControlPolicy> user_acl;
|
||||
|
@ -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<std::string::size_type>(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<rgw::auth::s3::RGWS3V2Extractor> strategy(g_ceph_context, store);
|
||||
try {
|
||||
auto result = strategy.authenticate(s);
|
||||
if (result.get_status() != decltype(result)::Status::GRANTED) {
|
||||
|
@ -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<std::string::size_type>(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<access_key_id_t,
|
||||
signature_t,
|
||||
string_to_sign_t>
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user