-
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\certificatecredentials\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了。