基于角色的访问控制是限制系统访问某些用户的一种方法。在BigchainDB中,这个函数允许创建角色和权限层次结构作为资产。此外,用户可以被分配角色“代表”或“代表”其他用户或组。
在本指南的示例用例场景中,我们有不同的族(tribes)或用户组,它们具有不同的角色,属于一个族(tribes)的用户可以创建建议资产(proposal assets ),而其他人可以在BigchainDB块链上创建投票资产(vote assets)。
首先安装官方的BigchainDB JavaScript驱动程序、Python驱动程序或Java驱动程序:
# JavaScript driver
npm i bigchaindb-driver
# Python driver
pip install -U bigchaindb-driver
com.bigchaindb
bigchaindb-driver
1.0
然后,将其作为模块包含并连接到任何BigchainDB节点。
const BigchainDB = require('bigchaindb-driver')
const API_PATH = 'https://test.bigchaindb.com/api/v1/'
const conn = new BigchainDB.Connection(API_PATH)
from bigchaindb_driver import BigchainDB
conn = BigchainDB('https://test.bigchaindb.com')
BigchainDbConfigBuilder
.baseUrl("https://test.bigchaindb.com/").setup();
重要提示:BigchainDB RBAC模块在BigchainDB中不能开箱即用,并且插件智能资产需要加载特定的BigchainDB分支(kyber-master)。设置指令在智能资产存储库的README.md中可找到。
让我们创建应用程序。您将为Admin类型创建一个资产,该资产将充当应用程序的管理组。本教程将使用异步/等待函数:
const nameSpace = 'rbac-bdb-tutorial'
async function createApp(){
// Generate keypair for admin instance
const admin1 = new BigchainDB.Ed25519Keypair()
// Create admin user type. This is the asset representing the group of
// admins
const adminGroupAsset = {
ns: `${nameSpace}.admin`,
name: 'admin'
}
const adminGroupMetadata = {
canLink: [admin1.publicKey]
}
const adminGroupId = (await createNewAsset(admin1, adminGroupAsset,
adminGroupMetadata)).id
document.body.innerHTML ='Admin Group asset created
'
document.body.innerHTML +=adminGroupId.id
// Create admin user instance. This is a single user with admin role
// represented by an asset. Is the asset representing admin1 user
// Create app asset with admin1, the umbrella asset for representing the app
const appAsset = {
ns: nameSpace,
name: nameSpace
}
const appMetadata = {
canLink: adminGroupId
}
const appId = (await createNewAsset(admin1, appAsset, appMetadata)).id
console.log('App: ' + appId)
}
createNewAsset函数如下所示:
async function createNewAsset(keypair, asset, metadata) {
let condition = BigchainDB.Transaction.makeEd25519Condition(keypair.publicKey,
true)
let output = BigchainDB.Transaction.makeOutput(condition)
output.public_keys = [keypair.publicKey]
const transaction = BigchainDB.Transaction.makeCreateTransaction(
asset,
metadata,
[output],
keypair.publicKey
)
const txSigned = BigchainDB.Transaction.signTransaction(transaction,
keypair.privateKey)
let tx
await conn.postTransactionCommit(txSigned)
.then(retrievedTx => {
tx = retrievedTx
})
return tx
}
您刚刚生成了管理类型和应用程序资产,所以现在可以为这个RBAC示例创建所有其他资产,这些资产是用户(包括管理员)和族(tribe)。
function createUsers() {
const user1 = new BigchainDB.Ed25519Keypair()
const user2 = new BigchainDB.Ed25519Keypair()
const user3 = new BigchainDB.Ed25519Keypair()
const adminuser1Metadata = {
event: 'User Assigned',
date: new Date(),
timestamp: Date.now(),
publicKey: admin1.publicKey,
eventData: {
userType: 'admin'
}
}
// Admin user instance belongs to the AdminGroup
const adminUserId = (await createUser(admin1, adminGroupId, 'admin',
admin1.publicKey, adminuser1Metadata)).id
document.body.innerHTML ='Admin user asset created
'
document.body.innerHTML +=adminUserId
// Tribes are user groups
const tribe1Id = (await createType('tribe1', appId, adminGroupId)).id
document.body.innerHTML ='Tribe 1 asset created
'
document.body.innerHTML +=tribe1Id
const tribe2Id = (await createType('tribe2', appId, adminGroupId)).id
document.body.innerHTML ='Tribe 2 asset created
'
document.body.innerHTML +=tribe2Id
// create user instances
const user1Metadata = {
event: 'User Assigned',
date: new Date(),
timestamp: Date.now(),
publicKey: admin1.publicKey,
eventData: {
userType: 'tribe1'
}
}
// Create the asset representing user1 with the admin1 keys.
// Add it to tribe 1
const user1AssetId = (await createUser(admin1, tribe1Id, 'tribe1',
user1.publicKey, user1Metadata)).id
document.body.innerHTML ='User 1 asset created
'
document.body.innerHTML +=user1AssetId
// create user instances
const user2Metadata = {
event: 'User Assigned',
date: new Date(),
timestamp: Date.now(),
publicKey: admin1.publicKey,
eventData: {
userType: 'tribe2'
}
}
// user 2 added to tribe 2
// Is the asset representing user1
const user2AssetId = (await createUser(admin1, tribe2Id, 'tribe2',
user2.publicKey, user2Metadata)).id
document.body.innerHTML ='User 2 asset created
'
document.body.innerHTML +=user2AssetId
const user3Metadata = {
event: 'User Assigned',
date: new Date(),
timestamp: Date.now(),
publicKey: admin1.publicKey,
eventData: {
userType: 'tribe1'
}
}
// user 3 added to tribe 1
const user3AssetId = (await createUser(admin1, tribe1Id, 'tribe1',
user3.publicKey, user3Metadata)).id
document.body.innerHTML ='User 3 asset created
'
document.body.innerHTML +=user3AssetId
}
您已经创建了用户,其中一些属于族1,其他属于族2。现在是时候给不同的族不同的许可了。为此,您将为提案和投票创建资产类型。
async function usersToTribes(){
// Non users
// Proposal: only tribe 1 users can create proposal
const proposalGroupId = (await createType('proposal', appId, tribe1Id)).id
console.log('ProposalGroup: ' + proposalGroupId)
// Vote: only tribe 2 users can create vote
const voteGroupId = (await createType('vote', appId, tribe2Id)).id
document.body.innerHTML ='Vote group asset created
'
document.body.innerHTML +=voteGroupId
所以现在只需要创建来自不同用户的建议和投票。您将看到,只有部分用户能够创建提案,而另一些用户能够投票。
// create proposal by user 1 - should pass
const proposal1 = await createTypeInstance(user1, 'proposal',
proposalGroupId, { name: 'new proposal by user 1',
timestamp: Date.now() })
document.body.innerHTML ='Proposal group asset created
'
document.body.innerHTML +=proposal1.id
// create vote by user 2 - should pass
const vote1 = await createTypeInstance(user2, 'vote', voteGroupId,
{ name: 'new vote by user 2', timestamp: Date.now() })
document.body.innerHTML ='Vote instance created
'
document.body.innerHTML +=vote1.id
// create proposal by user 3 - should pass
const proposal2 = await createTypeInstance(user3, 'proposal',
proposalGroupId, { name: 'new proposal by user 3',
timestamp: Date.now() })
document.body.innerHTML ='Vote instance created
'
document.body.innerHTML +=proposal2.id
// create vote by user 1 - should fail
const vote2 = await createTypeInstance(user1, 'vote',
voteGroupId, { name: 'new vote by user 1', timestamp: Date.now() })
document.body.innerHTML ='Vote instance could not be created
'
document.body.innerHTML +=vote2.id
}