5.4 交易鉴权

5.4.1 账户权限相关概念

权限

EOS采用父子分层的权限结构,低级权限(子权限)由高级权限(父权限)派生而来,父权限拥有子权限所有的能力。子权限能做的事父权限也能做,但是反过来,父权限能做的事,子权限不一定能做。

  • owner 是最高等级权限,拥有owner权限就意味着拥有账户的所有权,我们可以把owner理解为超级管理员权限。
  • active 是owner的子权限,主要用来发送交易、投票或者进行高级别的账户修改操作。

权重

权限拥有者在权限中的重要程度,具体以不小于1的整数表示。

阈值

执行该权限的最低权重的临界值,大于此临界值就可以执行该权限了。

账户

执行操作的执行体,当一个账户被创建时,就具备了两种基本权限(permission)。每个权限绑定在一个公钥或多个公钥上,还可以绑定到另一个有效的账户的权限(permission)上。

账户权限由权限(permission)、对应公钥或另一个账户的权限(嵌套权限)、权重(weight)以及阈值(threshold)四个部分组成,账户下的权限结构如下:

5.4.2 交易鉴权过程

当执行一笔交易时,通过权限验证,可以开始执行,分成两步:

  1. 获取账户权限中的公钥,通过钱包找到私钥,然后通过私钥对交易进行签名;
  2. 从签名串中解出公钥,进行数字签名认证(查看公钥是否在账户权限中存在),如果存在则获取此公钥的权重,并比较权重是否大于权限的阈值,若大于阈值则鉴权通过;如果账户权限是多重嵌套权限,则需要把每个权限鉴权通过后的权重相加,把最后权重的总和与权限阈值做比较;

我们通过一个例子来说明权限的验证过程:
账户account1加载token合约,执行account1转账给account2,5个SDF代币,由account1执行;

./cleos set contract account1 ../../contracts/eosio.token -p [email protected]
./cleos push action account1 transfer ‘[ "account1", "account2", "5.00 SDF", "m" ]‘ -p [email protected]

创建账户时,系统同时会把账户下默认的权限设置好,写入chainbase数据库中,但可以通过命令修改账户下的权限的公钥,嵌套关系,权重,阈值;

比如:账户account1的权限表如下表所示:

因为账户account1的权限表中存在嵌套关系:[email protected],则也需要账户account2的权限表,如下表所示:

签名交易过程

做操作push action时,会最终打包成交易,接下来需要对交易做签名。
首先需要从账户account1中获取权限中的所有公钥,根据account1的权限表得到的required_keys如下:

{
    "EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC",
    "EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK"
}

其次,通过required_keys列表在钱包中找到对应的私钥,通过私钥对交易数据签名,生成两个个签名交易串signatures如下;

{
    "SIG_K1_K55WNdUGH3nvhqUmUXmZcYP7wvNs5sA3RGFrdgsoz1LtAfWSfWd4GTxAFvn66dFkzhGNBrPK4xPWvLcCnwLZzhDy8DhNXd",
    "SIG_K1_Y98JhdUGH3nvhqUmUXmZcYP7wvNdfgergrdrNJkjjkiUJjLKfWSfWd4GTxAFvn66dFgfdBrPK4xPWvLJIHIU4jI6iIiopL"
}

权限验证过程

先了解下公私钥的作用:

Private key: 5JaGpdrxRstRLZ9yNaCsAVhLmvYcAsyLRZ1BJiy8pEmDMZmNtij
Public  key: EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC

EOS系统采用的是DSA+ECC加密签名算法,主要用于数字签名和验证;
私钥主要用于签名,公钥用于验证;

所以,首先需要从签名串中解出公钥,作为权限验证的输入条件,根据上面的签名结果signatures,解出公钥列表provided_keys如下:

{
    "EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC",
    "EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK"
}

看下account1账户下的信息:

看下account2账户下的信息:

修改account1账户下的信息:

修改后的account1账户下的信息:

account1转账给account2,5个SDF代币:

现在我们分析下执行转账的具体鉴权过程:

我们在代码中关键点添加了一些打印信息,打印结果如下图:

trx.actions : 交易的所有action,需要验证的所有action
provided_keys :签名串中解出的公钥列表,用于数字签名认证,与权限对应的公钥做比对
permisions_to_satisfy : 需要验证的权限列表
authority_key : Key类型的权限列表
authority_accounts : 嵌套类型的权限列表
current weight : 鉴权过程中的当前权重,用做与阈值做比对的
current threshold : 鉴权需要的阈值

1.account1的active权限,阈值为2,权限部分由两部分组成:
(1).公钥key权限,EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK权限,权重为1;
(2).嵌套的账户account2权限,权重为1;account2的active权限对应EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC权限;

2.依次验证active权限:
(1).验证公钥key权限,系统会拿出active的key权限,对应的公钥是EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK,然后拿这个公钥在provided_keys中查找是否存在,如果存在,则判断对应的权重是否大于等于阈值,若满足,则鉴权通过,若不满足,则需要加上嵌套账户account2权限的权重,求总和后,判断是否满足;

(2).验证嵌套账户account2权限,账户account2的active的key权限,对应的公钥是EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC,然后拿这个公钥在provided_keys中查找是否存在,如果存在,则加上步骤一对应的权限,求出和,判断总的权重是否大于等于account1的active权限的阈值,若满足,则鉴权通过,若不满足,则鉴权失败;

从上面的打印结果可以看出,鉴权经过了两次判断,因为account1的active权限的阈值为2,而账户的的两个权限的权重都为1,所以需要两次;

5.4.3 源码分析鉴权过程

从上面的鉴权过程,我们可以知道,鉴权接口需要交易打包的actions和交易签名解出来的公钥列表;

看下action的定义:

从签名串中解出公钥:

recover_keys()函数会调用下面的代码,如图:

在push_transaction()会做鉴权验证,接口为check_authorization():

在check_authorization()中做验证时,分为三步:
(1).验证是否满足最小权限;
(2).把满足最小权限的权限加入到待验证的权限列表中;
(3).对权限列表中的权限依次验证;

把满足最小权限的权限加入到待验证的权限列表中后,看下 permissions_to_satisfy 的定义:
map<permission_level, fc::microseconds> permissions_to_satisfy;

开始验证权限:


因为weight_tally_visitor结构体重载了()操作符,所以在调用 visitor(permission_level_weight{permission, 1}) 时,会调用weight_tally_visitor结构体()操作符的重载函数;

在satisfied()函数时,会按权限类型分类验证;

先看下权限的分类定义:

递归调用key类型()的重载函数,判断权限是否满足权重大于等于阀值,如果大于等于阈值,则鉴权成功;

5.4.4 总结

总结:
1.有多个或多种权限的鉴权过程就是判断满足多个或多种权限对应的权重的总和是否大于等于执行者的权限阈值;
2.所有的嵌套的账户权限的验证,最终都转化为验证最小单位Key类型的权限验证;
3.最小单位Key类型权限的验证即对交易签名串的签名认证(证明是某个账户发起的交易),也就是验证该权限对应的公钥是否在签名串解出的公钥列表中存在;

链接

http://www.3heu.club:8008/
https://www.jianshu.com/p/0b7365ea43fe
https://blog.csdn.net/arm_snow/article/details/90318052

原文地址:https://blog.51cto.com/14267585/2396721

时间: 2024-11-08 20:29:22

5.4 交易鉴权的相关文章

鉴权,开放式授权,单点登陆

鉴权 鉴权(authentication)是指验证用户是否拥有访问系统的权利.传统的鉴权是通过密码来验证的.这种方式的前提是,每个获得密码的用户都已经被授权.在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请.这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份. 为了克服这种鉴权方式的缺点,需要一个更加可靠的鉴权方式.目前的主流鉴权方式是利用认证授权来验证数字签名的正

web系统中ACL, RBAC等鉴权系统的异同

ACL, 强调面向资源, 描述对具体资源对象的操作鉴权, 有诸如Zend_ACL(好用), symfony-acl(不好用)等实现 应用场景如:对一条帖子资源的增删改鉴权, 整个鉴权流程中, 权限部分是由具体帖子对象和增删改等操作共同构成的.授权的结果是将 "资源---操作" 组合授权给用户. RBAC,强调面向角色的权限节点鉴权, 描述对功能节点的鉴权,有诸如ThinkPHP-RBAC, sylius/rbac-bundle(symfony)等实现 应用场景如: 依据不同用户角色显示

带鉴权信息的SIP呼叫

INVITE sip:[email protected]/2.0 Via: SIP/2.0/UDP192.168.50.32:2445;branch=z9hG4bK-d8754z-244fd550d2729557-1---d8754z-;rport Max-Forwards: 70 Contact:<sip:[email protected]:2445> To: <sip:[email protected]> From:"1002"<sip:[email 

WebSocket 的鉴权授权方案

引子 WebSocket 是个好东西,为我们提供了便捷且实时的通讯能力.然而,对于 WebSocket 客户端的鉴权,协议的 RFC 是这么说的: This protocol doesn't prescribe any particular way that servers canauthenticate clients during the WebSocket handshake. The WebSocketserver can use any client authentication me

无线端安全登录与鉴权一之Kerberos

无线端登录与鉴权是安全登录以及保证用户数据安全的第一步,也是最重要的一步.之前做过一个安全登录与鉴权的方案,借这个机会,系统的思考一下,与大家交流交流 先介绍一下TX系统使用的Kerberos方案,参考了 http://blog.csdn.net/wulantian/article/details/42418231 的文章 一.概念介绍 Kerberos:起源于希腊神话,是一支守护着冥界长着3个头颅的神犬,在keberos Authentication中,Kerberos的3个头颅代表中认证过程

开放平台鉴权以及OAuth2.0介绍

OAuth 2.0 协议 OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容. OAuth 2.0不兼容1.0. 协议的参与者 RO (resource owner): 资源所有者,对资源具有授权能力的人. RS (resource server): 资源服务器,它存储资源,并处理对资源的访问请求. Client: 第三方应用,它获得RO的授权后便可以去访问RO的资源. AS (authoriz

api-gateway实践(7)鉴权场景和网关场景梳理、OAuth2待澄清问题列表

一.身份鉴权验证 1.业务请求 1.1.父元素声明了 "/GroupA/VersionB/*",子元素声明了 "/GroupA/VersionB/Cxxx",access="ROLE_XXXX" 身份识别: 有效token 无token.无效token   权限鉴别: 有权限: 无权限: 1.2.父元素声明了 "/GroupA/VersionB/*",子元素没有声明的 "/GroupA/VersionB/Dxxx&q

搭建一个分布式MongoDB鉴权集群

今天休假在家,测试并搭建了一个replica set shard MongoDB鉴权集群.replica set shard 鉴权集群中文资料比较少,本文是个人笔记,同时也希望对后来者有所帮助.本文仅是搭建步骤和Q&A,用于实际工作中的使用查阅,阅读者需要有分布式集群的理论基础. 关键字:Replica-Set Shard 副本 分片 鉴权 KeyFile auth MongoDB根据部署的不同,有两种添加鉴权的方式,分别是单实例的鉴权方式和KeyFile的鉴权方式.两种方式的共同点都是,先在没

ldap查询、鉴权

package cn.richinfo.ldap; import java.util.Iterator; import com.novell.ldap.LDAPAttribute; import com.novell.ldap.LDAPAttributeSet; import com.novell.ldap.LDAPConnection; import com.novell.ldap.LDAPEntry; import com.novell.ldap.LDAPException; import