Hyperledger Composer的权限控制

  1. 2     Identity和Participant和card
       这里是相关概念的一点解释,了解的可以跳过。。。
    Participant是区块链业务网络的参与者,可以进行:操作 assets,提交 transactions,与其他 participants 进行 assets 交换等业务
    Identity(身份)是 Fabric 区块链网络中的重要概念,它表示一个独立的用户身份,它由 Fabric CA 颁发,是权限控制的基础。一个 Participant 会拥有一个或多个 Identity 文档,以表示这个 Participant 的身份的多个方面;正如一个人可以通过护照、身份证、指纹、数字证书等多种文件证明他/她的身份。在与 Fabric 网络交互时,Participant 本身并不被允许直接与 Fabric 网络对话,因为它只是一个 resource,是一个资源实例;它必须通过被 Fabric CA 认可的 Identity 文档证明当前 Participant 的身份。也就是说:我们需要建立 Participant – Identity 的对应关系。
    Card 文件
    Business Network Card 文件(.card)是 Identity 的载体,它包含了到业务网络的连接信息,Identity 认证信息。执行 Issue Identity 时,会生成相应的 Card 文件;客户端连接业务网络时,就是通过指定 Card 名称(注意:并不是 Card 文件名称)来确认 Identity 的。

    Card 文件结构
    Card 文件是一个 zip 格式的压缩文件,主要有以下几个文件构成。

    metadata.json (Identity 的相关信息),示例:
    {
        "version": 1,
        "userName": "admin",
        "businessNetwork": "bikesharing-network",
        "enrollmentSecret": "adminpw"
    }
    <username>@<businessNetwork>即组成以后通过 --card 参数使用的 Card 名称。

    connection.json (到业务网络的连接信息),示例:

    {
        "name": "hlfv1",
        "x-type": "hlfv1",
        "x-commitTimeout": 300,
        "version": "1.0.0",
        "client": …,
        "channels": …,
        "organizations": …,
        "orderers": …,
        "peers": {
            "peer0.org1.example.com": {
                "url": "grpc://localhost:7051",
                "eventUrl": "grpc://localhost:7053"
            }
        },
        "certificateAuthorities": …
    }
    credentials\certificate

    credentials\privateKey

    credentials 文件夹下的两个文件(证书与私钥)是可选的。如果没有 credentials 文件夹,则 metadata.json 文件中的 enrollmentSecret 属性必须存在。如果 enrollmentSecret 属性存在,则在执行 Card 导出时,就会在导出的 Card 文件中包括 credentials 文件夹。
    3    ACL语言

    创建一个composer工程时一般默认生成下面两个acl规则。其意思就是系统管理员具有所有权限。card默认根据系统管理员证书创建。
    rule NetworkAdminUser {
        description: "Grant business network administrators full access to user resources"
        participant: "org.hyperledger.composer.system.NetworkAdmin"
        operation: ALL
        resource: "**"
        action: ALLOW
    }
     
    rule NetworkAdminSystem {
        description: "Grant business network administrators full access to system resources"
        participant: "org.hyperledger.composer.system.NetworkAdmin"
        operation: ALL
        resource: "org.hyperledger.composer.system.**"
        action: ALLOW
    }
    每个属性的一般格式为 property: "MATCH_EXPRESSION"。这些属性包括:
    description— 放在双引号中的一个人类可读的规则名称。示例:description: "This is a description"
    participant— 被允许或拒绝访问的参与者的完全限定名称,放在双引号中。可通过以下方式在 MATCH_EXPRESSION 中指定多个参与者:使用单个星号 (*) 通配符来表示“所有”,使用双星号 (**) 表示在一个命名空间中应用递归,或者使用 ANY 来匹配所有命名空间中的所有参与者。
    示例:
    •    participant: "org.acme.shipping.perishable.Grower"— 仅将规则应用于org.acme.shipping.perishable.Grower。
    •    participant: "org.acme.shipping.perishable.*"—将规则应用于 org.acme.shipping.perishable 命名空间中的所有参与者。
    •    participant: "org.acme.shipping.**"—将规则应用于 org.acme.shipping 命名空间中的所有参与者,并以递归方式将规则应用于它下方的所有命名空间。
    •    participant: "ANY"— 将规则应用于所有命名空间中的所有参与者。
    operation—MATCH_EXPRESSION 可能是 CREATE、READ、UPDATE、DELETE 或 ALL 中的一个或多个。多个值可以使用逗号分隔(例如 CREATE,READ 将同时授予对资源的 CREATE 和 READ 访问权)。单独使用 ALL 表示将该规则应用于所有操作。
    示例:
    •    operation: ALL— 将规则应用于所有 CRUD 操作。
    •    operation: CREATE— 仅将规则应用于 CREATE 操作
    •    operation: READ,UPDATE— 将规则应用于 READ 和 UPDATE 操作。
    resource— 定义了规则所应用到的“事物”。资源可以是来自业务模型的任何类(比如资产、参与者或事务)。通过使用通配符,还可以指定多个类,方式与上面的参与者相同。
    示例:
    •    resource: "org.acme.shipping.perishable.TemperatureReading"— 规则仅应用于org.acme.shipping.perishable.TemperatureReading 事务。
    •    resource: "org.acme.shipping.perishable.*"—规则应用于 org.acme.shipping.perishable 命名空间中的所有类。
    •    resource: "org.acme.shipping.**"—将规则应用于 org.acme.shipping 命名空间中的所有资源,并以递归方式将规则应用于它下方的所有命名空间。
    action— 在触发规则时应用的操作。应用以下操作之一:ALLOW 或 DENY,前者表示允许访问,后者表示拒绝访问指定参与者访问资源。
    示例:
    •    action: ALLOW— 允许访问指定资源。
    •    action: DENY— 拒绝访问指定资源。
    备注:如果您的网络没有 permissions.acl,则允许所有参与者访问(也就是说,访问权是完全开放的 — 没有资源级别的安全保护)。

    3.1    composer模拟测试代码     
    模型文件:
    namespace org.bikesharing.biznet


    abstract participant BaseParticipant identified by pid{
        o String pid
        o String name
    }

    participant BikeProvider extends BaseParticipant {
       
    }

    participant BikeUser extends BaseParticipant {
        
    }

    abstract asset BaseAsset identified by aid {
        o String aid
    }

    asset Bike extends BaseAsset {
        o String remark
        o String status  //0 初始态  1 投放  2 租用
    }

    abstract transaction BaseTransaction {
    }

    abstract transaction BikeTransaction extends BaseTransaction{
        --> Bike bike   
    }


    // 0 BikeProvider投放自行车
    transaction BikeReleaseTransaction extends BikeTransaction{
       
    }

    //用户租借自行车  因为在交易里需要更改 bike的状态 ,因此还需要bike assts的权限
    transaction BikeRentTransaction extends BikeTransaction {
        
    }


    logic文件.业务逻辑很简单仅测试acl用。BikeProvider投放自行车,自行车状态变为1.租车者租车,自行车状态变为2.
    /**
     * New script file
     */

    'use strict';
    /**
     * 
     * @param {org.bikesharing.biznet.Bike} bike
     */
    async function updateBike(bike) {
        // Get the asset registry for the bikes.
        const assetRegistry = await getAssetRegistry('org.bikesharing.biznet.Bike');
        // Update the bike status in the bikes registry.
        // All data validating will be handled before calling this method.
        await assetRegistry.update(bike);
    }

    /**
     * Processor function for BikeRentTransaction
     * @param {org.bikesharing.biznet.BikeRentTransaction} tx
     * @transaction
     */
    async function processBikeRentTransaction(tx) {

        tx.bike.status="2";
        await updateBike(tx.bike);
     
    }

    /**
     * Processor function for BikeReleaseTransaction
     * @param {org.bikesharing.biznet.BikeReleaseTransaction} tx
     * @transaction
     */
    async function processBikeReleaseTransaction(tx) {
        tx.bike.status="1";
        await updateBike(tx.bike);
       
    }
    ACL权限控制文件

    //管理员权限
    rule NetworkAdminUser {
        description: "Grant business network administrators full access to user resources"
        participant: "org.hyperledger.composer.system.NetworkAdmin"
        operation: ALL
        resource: "**"
        action: ALLOW
    }

    rule NetworkAdminSystem {
        description: "Grant business network administrators full access to system resources"
        participant: "org.hyperledger.composer.system.NetworkAdmin"
        operation: ALL
        resource: "org.hyperledger.composer.system.**"
        action: ALLOW
    }

    /////////////////////////////////////////////////////////////////////////
    //系统管理员拥有所有权限
    rule BusinessAdmin {    
        description: "Grant administrators full access to the bikesharing business network"
        participant: "org.hyperledger.composer.system.NetworkAdmin"
        operation: ALL
        resource: "org.bikesharing.biznet.**"
        action: ALLOW
    }

    rule NormalACL {
        description:  "Normal ACL to permit base access"
        participant: "org.hyperledger.composer.system.Participant"
        operation: ALL
        resource: "org.hyperledger.composer.system.**"
        action: ALLOW
    }

    rule Provider {
         description:  "自行车提供者拥有所有权限"
        participant: "org.bikesharing.biznet.BikeProvider"
        operation: ALL
        resource: "org.bikesharing.biznet.**"
        action: ALLOW  
    }

    //BikeUser需要bike的读和修改权限。
    rule BikeUser1 {
         description:  "自行车租借用户拥有自行车资产的读和修改权限"
        participant: "org.bikesharing.biznet.BikeUser"
        operation: READ,UPDATE
        resource: "org.bikesharing.biznet.Bike"
        action: ALLOW  
    }

    //BikeUser只有BikeRentTransaction交易权限,禁止做其它交易
    rule BikeUser2 {
         description:  "自行车租借用户拥有租借交易权限"
        participant: "org.bikesharing.biznet.BikeUser"
        operation: CREATE
        resource: "org.bikesharing.biznet.BikeRentTransaction"
        action: ALLOW  
    }

3.2    在composer-playground中定义一个Identity实现ACL控制
1,首先需要在test标签页创建一个BikeProvider的particpant.

2,在composer-playground中发合约后在编辑界面点右上角admin->ID Registry按钮 
3,在打开的页面中点击  Issue New ID 弹出对话框
 


4,创建Identity 并且绑定一个Participant类型. ID Name会到ca服务注册一个用户,用户名就是这里的 bp1.密码由ca随机生成. 在Participant输入框任意键,在弹出框选择Participant. 如上图。 上图意思是ca生成bp1,并且绑定这个 id为bp1的BikerProvider参与者。
5,点击 "Create New"按钮 ,出现下面对话框


6,点击"Add to wallet"会生成一个card.也可以在 Send it to someone else中导出这个card.
7,同样再生成一个BikeUser的Identity及card.回到主页如下:
 

 

发现在布署区多了2个card .bp1@bike2和bu1@bike2

点击.bp1@bike2的Connect now 则使用 bp1这个Identity连接链码,可以在这里测试acl是否正确。

 

8,因为我们配置bp1 particpant拥有所权限.用bp1身份在test页创建2个bike,然后提交BikeReleaseTransaction交易,发现自行状态已经变更.

9,现在使用bu1这个Identity进去测试。首先我们发现看不到刚才创建的 BikeUser和BikeProvider这两个Particpant的数据。我们没给这个bu1配置Particpant操作权限。说明权限已经生效。点击创建Particpant测试,提示没权限操作。

10,我们的示例定义了两个 Tansaction,逐一测试,发现只BikeRentTransaction操作成功。和我们定义的权限预期一致。

3.3    在composer-rest-server中使用acl
要使用acl需要开启用户认证. composer-rest-server使用步骤 利用composer命令或者playground中生成Identity Card文件----> Identity card文件导入到composer-rest-server -----> composer-rest-server中设置默认Identity (/wallet/{name}/setDefault)  ,--->使用composer-rest-server中的api

composer-rest-server的相关配置:
1, npm install -g passport-github
2, 在github配置策略
   1) https://github.com/settings/developers 注册一个新的application
   2)填入信息如下:
    Application name: Composer
    Homepage: http://localhost:3000/
   Application description: OAuth application for Composer
   Authorization callback URL: http://localhost:3000/auth/github/callback
   3)记住用户名和密码
3,在github注册完毕后配置环境变量 clientID和密码用github上注册的
 export COMPOSER_PROVIDERS='{
  "github": {
    "provider": "github",
    "module": "passport-github",
    "clientID": "REPLACE_WITH_CLIENT_ID",
    "clientSecret": "REPLACE_WITH_CLIENT_SECRET",
    "authPath": "/auth/github",
    "callbackURL": "/auth/github/callback",
    "successRedirect": "/",
    "failureRedirect": "/"
  }
}'
4,多用户模式启动composer-rest-server 
composer-rest-server -c  admin@bike2  -n always -m true -w true -p 3000
-m :表示多用户启动 
-n : 有冲突类型是否启用名称空间 取值 "always", "required", "never"
-w: 是否开启websocket服务
-p: 端口号


5,浏览器中输入 http://10.122.2.44:3000/auth/github 成功后会返回一串token.显示如下:

Access token显示的是github返回的认证后的token.同时在底部区域多了一个 Wallet的rest服务相关接口

/wallet/import   上传card文件,如果是第一个,会把这个card设置为默认用户Identity.

/wallet/{name}/setDefault :根据name设置默认的card.这个默认的card即调用合约时使用到里面的Identity相关信息并且传到链码(chaincode)里面。

/wallet/{name}/setDefault:导出card文件

/wallet : 查询有哪些card文件,或者默认card

6,从composer-playground中导出card,并且导入到composer-rest-server

7,通过/wallet/{name}/setDefault设置不同的identity测试

4    配置Identity的两种方式
   1)在composer-playground中配置Identity 见3.2

   2)使用composer identity issue 创建一个Identity card
       //创建一个和BikeUser#bu_2绑定的 card.  这个命令会到ca服务器注册一个用户 。用户名是--newUserId指定的名字。密码则由ca动态生成。同时包括这个的证书. 
注意:这个ID为bu2的BikeUser必须存在
      1,composer identity issue --card admin@bike2 --file bu2.card --newUserId bu2 --participantId 'resource:org.bikesharing.biznet.BikeUser#bu2'
      
      2,composer card import -f bu2.card   导入card.
   3)可以在composer-rest-server中作用这个card了。

猜你喜欢

转载自blog.csdn.net/foolone/article/details/81091577