RGW中的请求的认证过程
来源:互联网 发布:蝴蝶标本价格淘宝 编辑:程序博客网 时间:2024/05/21 04:43
RGW中的用户认证过程(keystone or rados backend)
用户s3用户请求的合法性验证过程:src/rgw/rgw_rest_s3.cc
Rgw的认证方式有两种一个是使用keystone认证;一个是使用rados自带的认证方式;根据配置判断是否使用keystone认证;如果配置了keystone方式,则keystone方式;(二选一)
int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s){ bool qsr = false; string auth_id; string auth_sign; time_t now; time(&now); /* neither keystone and rados enabled; warn and exit! */ if (!store->ctx()->_conf->rgw_s3_auth_use_rados && !store->ctx()->_conf->rgw_s3_auth_use_keystone) { dout(0) << "WARNING: no authorization backend enabled! Users will never authenticate." << dendl; return -EPERM; } if (s->op == OP_OPTIONS) { init_anon_user(s); return 0; }/* initialize auth_id and auth_sign */ if (!s->http_auth || !(*s->http_auth)) { auth_id = s->info.args.get("AWSAccessKeyId"); if (auth_id.size()) { auth_sign = s->info.args.get("Signature"); string date = s->info.args.get("Expires"); time_t exp = atoll(date.c_str()); if (now >= exp) return -EPERM; qsr = true; } else { /* anonymous access */ init_anon_user(s); return 0; } } else { if (strncmp(s->http_auth, "AWS ", 4)) return -EINVAL; string auth_str(s->http_auth + 4); int pos = auth_str.rfind(':'); if (pos < 0) return -EINVAL; auth_id = auth_str.substr(0, pos); auth_sign = auth_str.substr(pos + 1); } /* try keystone auth first */ int keystone_result = -EINVAL; if (store->ctx()->_conf->rgw_s3_auth_use_keystone && !store->ctx()->_conf->rgw_keystone_url.empty()) { dout(20) << "s3 keystone: trying keystone auth" << dendl;//构造keystone验证的验证器。 RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx()); string token;//获取用于计算签名的请求头信息(s3认证) if (!rgw_create_s3_canonical_header(s->info, &s->header_time, token, qsr)) { dout(10) << "failed to create auth header\n" << token << dendl; } else { keystone_result = keystone_validator.validate_s3token(auth_id, token, auth_sign); if (keystone_result == 0) { // Check for time skew first time_t req_sec = s->header_time.sec(); if ((req_sec < now - RGW_AUTH_GRACE_MINS * 60 || req_sec > now + RGW_AUTH_GRACE_MINS * 60) && !qsr) { dout(10) << "req_sec=" << req_sec << " now=" << now << "; now - RGW_AUTH_GRACE_MINS=" << now - RGW_AUTH_GRACE_MINS * 60 << "; now + RGW_AUTH_GRACE_MINS=" << now + RGW_AUTH_GRACE_MINS * 60 << dendl; dout(0) << "NOTICE: request time skew too big now=" << utime_t(now, 0) << " req_time=" << s->header_time << dendl; return -ERR_REQUEST_TIME_SKEWED; } s->user.user_id = keystone_validator.response.token.tenant.id; s->user.display_name = keystone_validator.response.token.tenant.name; // wow. /* try to store user if it not already exists */ if (rgw_get_user_info_by_uid(store, keystone_validator.response.token.tenant.id, s->user) < 0) { int ret = rgw_store_user_info(store, s->user, NULL, NULL, 0, true); if (ret < 0) dout(10) << "NOTICE: failed to store new user's info: ret=" << ret << dendl; } s->perm_mask = RGW_PERM_FULL_CONTROL; } } } /* keystone failed (or not enabled); check if we want to use rados backend */ if (!store->ctx()->_conf->rgw_s3_auth_use_rados && keystone_result < 0) return keystone_result; /* now try rados backend, but only if keystone did not succeed */ if (keystone_result < 0) { /* get the user info */ if (rgw_get_user_info_by_access_key(store, auth_id, s->user) < 0) { dout(5) << "error reading user info, uid=" << auth_id << " can't authenticate" << dendl; return -ERR_INVALID_ACCESS_KEY; } /* now verify signature */string auth_hdr;//生成s3token if (!rgw_create_s3_canonical_header(s->info, &s->header_time, auth_hdr, qsr)) { dout(10) << "failed to create auth header\n" << auth_hdr << dendl; return -EPERM; } dout(10) << "auth_hdr:\n" << auth_hdr << dendl; time_t req_sec = s->header_time.sec(); if ((req_sec < now - RGW_AUTH_GRACE_MINS * 60 || req_sec > now + RGW_AUTH_GRACE_MINS * 60) && !qsr) { dout(10) << "req_sec=" << req_sec << " now=" << now << "; now - RGW_AUTH_GRACE_MINS=" << now - RGW_AUTH_GRACE_MINS * 60 << "; now + RGW_AUTH_GRACE_MINS=" << now + RGW_AUTH_GRACE_MINS * 60 << dendl; dout(0) << "NOTICE: request time skew too big now=" << utime_t(now, 0) << " req_time=" << s->header_time << dendl; return -ERR_REQUEST_TIME_SKEWED; } map<string, RGWAccessKey>::iterator iter = s->user.access_keys.find(auth_id); if (iter == s->user.access_keys.end()) { dout(0) << "ERROR: access key not encoded in user info" << dendl; return -EPERM; } RGWAccessKey& k = iter->second; if (!k.subuser.empty()) { map<string, RGWSubUser>::iterator uiter = s->user.subusers.find(k.subuser); if (uiter == s->user.subusers.end()) { dout(0) << "NOTICE: could not find subuser: " << k.subuser << dendl; return -EPERM; } RGWSubUser& subuser = uiter->second; s->perm_mask = subuser.perm_mask; } else s->perm_mask = RGW_PERM_FULL_CONTROL;string digest;//生成s3 token int ret = rgw_get_s3_header_digest(auth_hdr, k.key, digest); if (ret < 0) { return -EPERM; } dout(15) << "calculated digest=" << digest << dendl; dout(15) << "auth_sign=" << auth_sign << dendl; dout(15) << "compare=" << auth_sign.compare(digest) << dendl; if (auth_sign != digest) { return -ERR_SIGNATURE_NO_MATCH; } if (s->user.system) { s->system_request = true; dout(20) << "system request" << dendl; s->info.args.set_system(); string effective_uid = s->info.args.get(RGW_SYS_PARAM_PREFIX "uid"); RGWUserInfo effective_user; if (!effective_uid.empty()) { ret = rgw_get_user_info_by_uid(store, effective_uid, effective_user); if (ret < 0) { ldout(s->cct, 0) << "User lookup failed!" << dendl; return -ENOENT; } s->user = effective_user; } } } /* if keystone_result < 0 */ // populate the owner info s->owner.set_id(s->user.user_id); s->owner.set_name(s->user.display_name); return 0;}
0 0
- RGW中的请求的认证过程
- CEPH RGW处理请求过程
- RGW处理请求中获取handler过程
- rgw中的数据模型
- ceph rgw中的md_config_obs_t类
- 生成RGW的火焰图
- ceph-deploy的rgw命令
- SIP中的Digest认证过程
- 3G接入过程中的安全认证是如何实现的?
- sip的认证过程
- OAuth认证的过程
- TPM的认证过程
- shiro认证的过程
- ceph rgw中所使用的池子
- Ceph rgw CephContext的属性_service_thread
- https中的数字证书认证过程解析
- https中的数字证书认证过程解析
- Oauth认证过程的认识
- listview回滚到顶部
- com.android.dex.DexIndexOverflowException: Cannot merge new index 66299 into a non-jumbo instruction
- SQL基础知识1
- 数据结构—图
- python 编码方式总结
- RGW中的请求的认证过程
- Android之简易音乐播发器
- 对图片进行压缩
- 用两个栈实现队列
- JPA学习笔记
- Ubuntu 14.04 安装wine QQ方法
- MFC编程入门(MFC消息映射机制概述)
- 【LabVIEW之小技巧】用LabVIEW设置系统时间
- 旋转数组的最小数字