.set_default(false)
.set_description("Should S3 authentication use Keystone."),
+ Option("rgw_s3_auth_order", Option::TYPE_STR, Option::LEVEL_ADVANCED)
+ .set_default("external, local")
+ .set_description("Authentication strategy order to use for s3 authentication")
+ .set_long_description(
+ "Order of authentication strategies to try for s3 authentication, the allowed "
+ "options are a comma separated list of engines external, local. The "
+ "default order is to try all the externally configured engines before "
+ "attempting local rados based authentication"),
+
Option("rgw_barbican_url", Option::TYPE_STR, Option::LEVEL_ADVANCED)
.set_default("")
.set_description("URL to barbican server."),
}
public:
+ using engine_map_t = std::map <std::string, std::reference_wrapper<const Engine>>;
+ void add_engines(const std::vector <std::string>& auth_order,
+ engine_map_t eng_map)
+ {
+ auto ctrl_flag = Control::SUFFICIENT;
+ for (const auto &eng : auth_order) {
+ // fallback to the last engine, in case of multiple engines, since ctrl
+ // flag is sufficient for others, error from earlier engine is returned
+ if (&eng == &auth_order.back() && eng_map.size() > 1) {
+ ctrl_flag = Control::FALLBACK;
+ }
+ const auto kv = eng_map.find(eng);
+ if (kv != eng_map.end()) {
+ add_engine(ctrl_flag, kv->second);
+ }
+ }
+ }
+
+ std::vector<std::string> parse_auth_order(CephContext* const cct)
+ {
+ std::vector <std::string> result;
+
+ const std::set <boost::string_view> allowed_auth = { "external", "local" };
+ std::vector <std::string> default_order = { "external", "local"};
+ // supplied strings may contain a space, so let's bypass that
+ boost::split(result, cct->_conf->rgw_s3_auth_order,
+ boost::is_any_of(", "), boost::token_compress_on);
+
+ if (std::any_of(result.begin(), result.end(),
+ [allowed_auth](boost::string_view s)
+ { return allowed_auth.find(s) == allowed_auth.end();})){
+ return default_order;
+ }
+ return result;
+ }
+
AWSAuthStrategy(CephContext* const cct,
rgw::auth::ImplicitTenants& implicit_tenant_context,
RGWRados* const store)
add_engine(Control::SUFFICIENT, anonymous_engine);
}
+ auto auth_order = parse_auth_order(cct);
+ engine_map_t engine_map;
/* The external auth. */
- Control local_engine_mode;
if (! external_engines.is_empty()) {
- add_engine(Control::SUFFICIENT, external_engines);
-
- local_engine_mode = Control::FALLBACK;
- } else {
- local_engine_mode = Control::SUFFICIENT;
+ engine_map.insert(std::make_pair("external", std::cref(external_engines)));
}
-
/* The local auth. */
if (cct->_conf->rgw_s3_auth_use_rados) {
- add_engine(local_engine_mode, local_engine);
+ engine_map.insert(std::make_pair("local", std::cref(local_engine)));
}
+ add_engines(auth_order, engine_map);
}
const char* get_name() const noexcept override {