您的位置:首页 > 其它

keystone 身份验证流程(3)

2013-07-19 17:28 183 查看
本文地址:/article/1378955.html

quantum端采用的身份验证。

/etc/quantum/api-paste.ini中

[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
auth_host = 172.16.4.1
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = quantum
admin_password = quantum


这里配置了验证信息,以及采用的验证函数。

验证采用的是keystone.middleware.auth_token的filter_factory函数。

def filter_factory(global_conf, **local_conf):
    """Returns a WSGI filter app for use with paste.deploy."""
    conf = global_conf.copy()
    conf.update(local_conf)

    def auth_filter(app):
        return AuthProtocol(app, conf)
    return auth_filter


AuthProtocal类,用于WSGI程序,当请求到来时,调用__call__方法。

def __call__(self, env, start_response):

    self._remove_auth_headers(env)
    user_token = self._get_user_token_from_header(env)
    token_info = self._validate_user_token(user_token)
    user_headers = self._build_user_headers(token_info)
    self._add_headers(env, user_headers)
    return self.app(env, start_response)


首先,从信息头中取得用户传来的token,即user_token

_get_user_token_from_header

def _get_user_token_from_header(self, env):
       
    token = self._get_header(env, 'X-Auth-Token',
                             self._get_header(env, 'X-Storage-Token'))
    return token
X-Auth-Token为QuantumClient端包装好的token。

取得token后,需要验证该token是否有效。

def _validate_user_token(self, user_token, retry=True):
        
    cached = self._cache_get(user_token)
    if cached:
        return cached
    if cms.is_ans1_token(user_token):
        verified = self.verify_signed_token(user_token)
        data = json.loads(verified)
    else:
        data = self.verify_uuid_token(user_token, retry)
        self._cache_put(user_token, data)
    return data
首先判断一下user_token是否在缓存中,如果有,直接通过。如果没有,需要从keystone获取token,然后与用户提交的user_token比较。

对于cms.is_ans1_token不清楚要干什么,认为无关紧要,可以先略过。

def verify_uuid_token(self, user_token, retry=True):

    headers = {'X-Auth-Token': self.get_admin_token()}
    response, data = self._json_request('GET',
                                        '/v2.0/tokens/%s' % user_token,
                                        additional_headers=headers)

    if response.status == 200:
        self._cache_put(user_token, data)
        return data
这里有一个get_admin_token,其实很好理解,相当于有一个管理员,它先向keystone验证身份,管理员与keystone通信也需要token来验证管理员身份。

然后管理员拿着用户传递来的user_token向keystone询问,user_token是否有效。

这个管理员,就是api-paste.ini中配置的。

auth_host = 172.16.4.1
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = quantum
admin_password = quantum


如果返回的状态码为200,则说明用户提交的user_token有效,将其放入缓存,下次就不需要验证了。

否则,当然是拒绝访问啦。

附:

AuthProtocal类的__call__方法。

def __call__(self, env, start_response):

    self._remove_auth_headers(env)
    user_token = self._get_user_token_from_header(env)
    token_info = self._validate_user_token(user_token)
    user_headers = self._build_user_headers(token_info)
    self._add_headers(env, user_headers)
    return self.app(env, start_response)


其中_build_user_header中,将一些信息加入信息头中,为后续权限认证提供必要的信息。

rval = {
            'X-Identity-Status': 'Confirmed',
            'X-Tenant-Id': tenant_id,
            'X-Tenant-Name': tenant_name,
            'X-User-Id': user_id,
            'X-User-Name': user_name,
            'X-Roles': roles,
            # Deprecated
            'X-User': user_name,
            'X-Tenant': tenant_name,
            'X-Role': roles,
        }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: