从Keystone的配置文件中,我们可见,Token的提供者目前支持四种。 Token Provider:UUID, PKI, PKIZ, or Fernet

结合源码及官方文档,我们用一个表格来阐述一下它们之间的差异。

接下去,从源码上来进一步分析流程。

(1)首先,uuid,这种方式较简单,没有特别的加密、编码流程,核心的生成过程,即 uuid.uuid4().hex,生成一串友好的序列。

(2)PKI的流程,首先需要使用 keystone-manage pki_setup命令生成CA及相关的令牌机制,其代码如下所示:

def _get_token_id(self, token_data):
        try:

token_json = jsonutils.dumps(token_data, cls=utils.PKIEncoder)
            token_id = str(cms.cms_sign_token(token_json,
                                              CONF.signing.certfile,
                                              CONF.signing.keyfile))   #DEFAULT_TOKEN_DIGEST_ALGORITHM=sha256

其中,‘token_data’是获取的user、role、endpoint、catlog等信息集合,而最重要的语句是cms使用签名生成token的过程:cms_sign_token,使用默认的sha256方式加密,处理过程使用process,进行数据的读取、处理,

process = subprocess.Popen(['openssl', 'cms', '-sign',
                                 '-signer', signing_cert_file_name,
                                 '-inkey', signing_key_file_name,
                                 '-outform', 'PEM',
                                 '-nosmimecap', '-nodetach',
                                 '-nocerts', '-noattr',
 
                                 '-md', message_digest, ],
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                close_fds=True)

最后output, err = process.communicate(data) 生成Token-id,这个过程涉及到openssl相关的加密技术,再次不作详述。我们只需清楚这个生成的大致流程。

(3)PKIZ的Token生成流程,和PKI类似,即在它的基础上进行的压缩,核心逻辑如下:

def _get_token_id(self, token_data):
        try:

token_json = jsonutils.dumps(token_data, cls=utils.PKIEncoder)
            token_id = str(cms.pkiz_sign(token_json,
                                         CONF.signing.certfile,
                                         CONF.signing.keyfile))

和PKI不同的是采用cms.pkiz_sign这个过程,进一步看这个过程,

def pkiz_sign(text,
               signing_cert_file_name,
               signing_key_file_name,
               compression_level=6,
               message_digest=DEFAULT_TOKEN_DIGEST_ALGORITHM):
     signed = cms_sign_data(text,

signing_cert_file_name,
                            signing_key_file_name,
                            PKIZ_CMS_FORM,
                            message_digest=message_digest)
  
     compressed = zlib.compress(signed, compression_level)
     encoded = PKIZ_PREFIX + base64.urlsafe_b64encode(   #PKIZ_PREFIX =pkiz_
         compressed).decode('utf-8')
     return encoded

在PKI原来的基础上,引入了ZIib压缩,并且使用pkiz_作为token的开头。

(4)Fernet的技术,也需要首先使用命令keystone-manage fernet_setup生成必要的令牌信息,只是它有0,1版本的区分,并且可以指定版本的个数,默认是不超过3个。

(猜测这个是为了提高安全性,和轮询替换相关)Fernet的Token-id生成过程,和参数scope有很大的关系,它的核心代码中,支持Project模式、Domain模式、无模式等等,处理方法略有差异,因此Fernet的Token的逻辑,与用户的项目、域有很大的关系,Token-id的生成随机因素降低了。我们以其中Projec的模式进行分析。

payload = FederatedProjectScopedPayload.assemble(
user_id,
methods,
project_id,
expires_at,
audit_ids,
federated_info)
versioned_payload = (version,) + payload
serialized_payload = msgpack.packb(versioned_payload)
token = self.pack(serialized_payload)
从上面的代码中,可见首先是对负载数据payload的处理,组装过程,(应该是一个数理学家设计的。。。)
b_user_id = cls.attempt_convert_uuid_hex_to_bytes(user_id)  
             #user_id 传进来前 u'b8aff9260dba489a831300630da4079f' ->后 UUID('b8aff926-0dba-489a-8313-00630da4079f')
methods = auth_plugins.convert_method_list_to_integer(methods)  列表对应int的方法对应的是2*int(methods)
b_project_id = cls.attempt_convert_uuid_hex_to_bytes(project_id)  
expires_at_int = cls._convert_time_string_to_int(expires_at)   过期时间的整数形式表示
b_audit_ids = list(map(provider.random_urlsafe_str_to_bytes,   
                            audit_ids))                 审计为列表,并用随机的二进制生成

组装过程返回一个列表,进一步组成带有version的负载,然后加密crypto.encrypt(payload).rstrip('='),最后然后进行编码处理,返回Token-id。

通过以上四种的Token生成方式分析,可见每种方式都有优缺点,如果希望少去和Keystone交互,减少认证请求带宽,可以采用PKI、PKIZ、Fernet的方式,而这几种方式的逻辑各有差异,涉及到加密方法的安全性,CA的权威性,这都需要进一步斟酌,uuid是keystone目前版本默认的安装方式,其使用简单,只是存在每次请求token都需要和keytone交互。总之,它们的存在都有自己的优跟缺。

Keystone几种token生成的方式分析的更多相关文章

  1. Django-jwt token生成源码分析

    一. 认证的发展历程简介 这里真的很简单的提一下认证的发展历程.以前大都是采用cookie.session的形式来进行客户端的认证,带来的结果就是在数据库上大量存储session导致数据库压力增大,大 ...

  2. (转)理解Keystone的四种Token

    Token 是什么 通俗的讲,token 是用户的一种凭证,需拿正确的用户名/密码向 Keystone 申请才能得到.如果用户每次都采用用户名/密码访问 OpenStack API,容易泄露用户信息, ...

  3. 单点登录(十四)-----实战-----cas5.0.x登录mongodb验证方式常规的四种加密的思考和分析

    我们在上一篇文章中已经讲解了cas4.2.X登录启用mongodb验证方式 单点登录(十三)-----实战-----cas4.2.X登录启用mongodb验证方式完整流程 但是密码是明文存储的,也就是 ...

  4. 三种Tomcat集群方式的优缺点分析

    三种Tomcat集群方式的优缺点分析 2009-09-01 10:00 kit_lo kit_lo的博客 字号:T | T 本文对三种Tomcat集群方式的优缺点进行了分析.三种集群方式分别是:使用D ...

  5. Wps 2013 拼音标注两种方式分析

    Wps 2013 拼音标注两种方式分析 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...

  6. 鸿蒙内核源码分析(进程通讯篇) | 九种进程间通讯方式速揽 | 百篇博客分析OpenHarmony源码 | v28.03

    百篇博客系列篇.本篇为: v28.xx 鸿蒙内核源码分析(进程通讯篇) | 九种进程间通讯方式速揽 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁当 ...

  7. 讨论两种Redis中Token的存储方式

    摘要:本文讨论一个问题:存储token时,token与对应用户id谁来作为key? 问题起源问题起源于要给公司的后台管理系统添加权限管理,选用的是开源框架shiro,而原本系统上是采用token做了登 ...

  8. 快速理解 session/token/cookie 认证方式

    目录 目录 cookie session token cookie Web Application 一般以 HTTP 协议作为传输协议, 但 HTTP 协议是无状态的. 也就是说 server-sid ...

  9. apigw鉴权分析(1-3)百度 AI - 鉴权方式分析

    http://ai.baidu.com/docs#/Begin/top 一.访问入口 二.鉴权方式分析 1.鉴权认证方式一 - access_token - 针对HTTP API调用者 2.鉴权认证方 ...

随机推荐

  1. 【leetcode 简单】 第六十八题 二叉搜索树的最近公共祖先

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...

  2. 【leetcode 简单】 第五十六题 快乐数

    编写一个算法来判断一个数是不是“快乐数”. 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1.如 ...

  3. 2017ACM暑期多校联合训练 - Team 9 1010 HDU 6170 Two strings (dp)

    题目链接 Problem Description Giving two strings and you should judge if they are matched. The first stri ...

  4. 产品排序 product

    评测传送门 [问题描述] 你是一个公司的员工,你会按时间顺序受到一些产品的订单,你需要用一个栈来改变这些订单的顺序(每个产品都必须入栈和出栈一次). 按初始顺序,每次可以将一个产品入栈,或将栈顶产品弹 ...

  5. Python练习-递归二分算法

    # 编辑者:闫龙 #递归,二分算法演示 l = [i for i in range(1,100)]#定义一个列表l,并追加1-99的所有数字 def FindNum(num,l):#定义函数FindN ...

  6. window下卸载MySQL

    更多内容推荐微信公众号,欢迎关注: 网上找来的,留在这做个备份. 1.控制面板里的增加删除程序内进行删除 2.删除MySQL文件夹下的my.ini文件,如果备份好,可以直接将文件夹全部删除 3.开始- ...

  7. git 配置 SSH密钥

    1.登录用户 $ git config --global user.name "geekfeier" $ git config --global user.email " ...

  8. faskclick

        PC网页上的大部分操作都是用鼠标的,即响应的是鼠标事件,包括mousedown.mouseup.mousemove和click事件.一次点击行为,事件的触发过程为:mousedown -> ...

  9. thinkphp报错Call to undefined method app\index\controller\Index::fetch()

    因为要写一个系统,所以又重新下载了thinkphp,然后安装了一下.回忆起这个问题很容易让新手朋友费解.会出现如下报错:Call to undefined method app\index\contr ...

  10. -bash: /bin/rm: Argument list too long的解决办法【转】

    当目录下文件太多时,用rm删除文件会报错: -bash: /bin/rm: Argument list too long 提示文件数目太多. 解决的办法是使用如下命令: ls | xargs -n 1 ...