using RGWValidateKeystoneToken = \
rgw::keystone::Service::RGWValidateKeystoneToken;
+ bool admin_token_retried = false;
+
+admin_token_retry:
+
/* The container for plain response obtained from Keystone. It will be
* parsed token_envelope_t::parse method. */
ceph::bufferlist token_body_bl;
}
std::string admin_token;
- if (rgw::keystone::Service::get_admin_token(dpp, token_cache, config,
- y, admin_token) < 0) {
+ bool admin_token_cached = false;
+ int ret = rgw::keystone::Service::get_admin_token(dpp, token_cache, config,
+ y, admin_token, admin_token_cached);
+ if (ret < 0) {
throw -EINVAL;
}
validate.set_url(url);
- int ret = validate.process(y);
+ ret = validate.process(y);
/* NULL terminate for debug output. */
token_body_bl.append(static_cast<char>(0));
* 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) {
+
+ /* If admin token is invalid we should expire it from the cache and
+ try one last time without the cache. */
+ bool admin_token_unauthorized = (validate.get_http_status() ==
+ RGWValidateKeystoneToken::HTTP_STATUS_UNAUTHORIZED);
+
+ if (admin_token_unauthorized && admin_token_cached) {
+ ldpp_dout(dpp, 20) << "invalidating admin_token cache due to 401" << dendl;
+ token_cache.invalidate_admin(dpp);
+
+ if (!admin_token_retried) {
+ ldpp_dout(dpp, 20) << "retrying with uncached admin_token" << dendl;
+ admin_token_retried = true;
+ goto admin_token_retry;
+ }
+ }
+
+ /* If admin token is invalid or token supplied by client is non-existent. */
+ if (admin_token_unauthorized || validate.get_http_status() ==
+ RGWValidateKeystoneToken::HTTP_STATUS_NOTFOUND) {
ldpp_dout(dpp, 5) << "Failed keystone auth from " << url << " with "
<< validate.get_http_status() << dendl;
return boost::none;
/* get authentication token for Keystone. */
std::string admin_token;
+ bool admin_token_cached = false;
int ret = rgw::keystone::Service::get_admin_token(dpp, token_cache, config,
- y, admin_token);
+ y, admin_token, admin_token_cached);
if (ret < 0) {
ldpp_dout(dpp, 2) << "s3 keystone: cannot get token for keystone access"
<< dendl;
/* get authentication token for Keystone. */
std::string admin_token;
+ bool admin_token_cached = false;
int ret = rgw::keystone::Service::get_admin_token(dpp, token_cache, config,
- y, admin_token);
+ y, admin_token, admin_token_cached);
if (ret < 0) {
ldpp_dout(dpp, 2) << "s3 keystone: cannot get token for keystone access"
<< dendl;