在系统访问api时,都要经过auth_token认证,只有认证成功才能继续访问api,所以弄清api认证的流程很有必要。
token认证包括了三个认证过程,即:cache认证,本地认证和远程认证;
1、根据token信息从token cache获取token id 和具体的token信息(json字符串,cached);返回cached;
2、如果token cache中没有,则使用cms对token字符串进行解析认证;返回解析后的token信息,然后将计算是否超时;最后将没超时的token信息保存在 token cache中;返回解析后的字符串;
3、如果cms解析失败,则进行远程token认证,即访问keystone server进行token 认证;
4、如果远程认证成功,将计算是否超时;最后将没超时的token信息保存在 token cache中;返回解析后的字符串;
5、如果远程认证失败,则抛出认证失败异常;
每个api应用都有个api-paste.ini文件,里面定义了访问应用的路径以及访问的过滤器filter。下面以neutron的api-paste.init文件为例:
[composite:neutron] use = egg:Paste#urlmap /: neutronversions /v2.0: neutronapi_v2_0
[composite:neutronapi_v2_0] use = call:neutron.auth:pipeline_factory noauth = request_id catch_errors extensions neutronapiapp_v2_0 keystone = request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0 ...... [filter:authtoken] paste.filter_factory = keystonemiddleware.auth_token:filter_factory |
在文件中,可以看到访问应用会先经过authtoken过滤器,过滤器定义为:keystonemiddleware.auth_token:filter_factory.
def filter_factory(global_conf, **local_conf): conf = global_conf.copy() conf.update(local_conf) def auth_filter(app): return AuthProtocol(app, conf) return auth_filter |
Filter_factory返回一个AuthProtocol对象。Filter在处理请求时会调用__call__函数。
class AuthProtocol(object): def __call__(self, env, start_response): def _fmt_msg(env): msg = (&# |