微點存取控制庫使用戶外的範例

本主題提供如何使用此內容庫與鏈碼的一些範例。已呼叫這些假設 Init() 來建立啟動安裝實體,且 Init()invoke() 的呼叫程式為 "%CN%frank.thomas@example.com"。應用程式中的一般流程是建立一些初始存取控制清單,用來授予或拒絕其他實體的存取。

初始化

呼叫 Initialization() 以在建立鏈碼時建立啟動安裝實體。舉例而言:

import "chaincodeACL"
func (t \*SimpleChaincode) Init(nil, stub shim.ChaincodeStubInterface) pb.Response
{
         err := chaincodeACL.Initialization(stub)
}

建立新 ACL

import "chaincodeACL"
...
{

**ACLMgr**  := chaincodeACL.NewACLManager(nil, stub) // Not specify identity, use caller's identity as default.

// Define a new ACL
**newACL**  := chaincodeACL.ACL{

    "AllowAdmins",   // ACL name
    "Allow admins full access",  // Description
    []string{"CREATE","READ","UPDATE","DELETE"},    // Accesses allowed or not
    true, // Allowed
    []string{"%CN%bob.dole@example.com","%OU%example.com,"%GRP%admins"}, // Initial identity patterns
    ".ACLs.acl", // Start with bootstrap ACL

}

// Add this ACL with default identity (caller's identify here)
err :=  **ACLMgr**.Create( **newACL** , nil)

}

現在我們有新的 ACL,我們可以使用它來修改可以執行特定作業的人員。因此,我們將先將此新的 ACL 新增至啟動安裝群組 .Groups,以允許任何管理員建立群組。

新增 ACL 至群組

import "chaincodeACL"
…
{

  **groupMgr**  := chaincodeACL.NewGroupManager(nil, stub) // Not specify identity, use caller's identity as default.
  err :=  **groupMgr**.AddAfterACL(

    ".Groups",     // Bootstrap group name
    ".Groups.ACL", // Which ACL to add after
    "AllowAdmins", // The new ACL to add
    nil            // with default identity that's frank.thomas

)

}

這會在初始啟動安裝 ACL 之後,將 AllowAdmins ACL 新增至啟動安裝群組 .Groups。因此,這可確保 Frank Thomas 仍能在 .Groups 上執行作業,因為 ACL 授予其權限是清單中的第一個權限。但現在符合 AllowAdmins ACL 的任何人都可以執行 CREATE、READ、UPDATE 或 DELETE 作業 (他們現在可以建立新的群組)。

建立新群組

管理員現在可以建立新群組:

import "chaincodeACL"
...
{

...
  // Define a new group.
  **newGroup**  := chaincodeACL.Group{

      "AdminGrp",   // Name of the group
      "Administrators of the app",   // Description of the group
      {"%CN%jill.muller@example.com","%CN%ivan.novak@example.com","%ATTR%role=admin"},
      []string{"AllowAdmins"},   // The ACL for the group

    }

  **groupMgr**  := chaincodeACL.NewGroupManager(nil, stub)   // Not specify identity, use caller's identity as default.
  err :=  **groupMgr**.Create( **newGroup** , bob\_garcia\_certificate)   // Using a specific certificate

...
}

這個呼叫使用 Bob Garcia (使用他的憑證) 的明確識別來嘗試與建立新群組。由於 Bob Garcia 符合 AllowAdmins ACL 中的樣式,且該 ACL 的成員可以在啟動安裝群組 .Groups 上執行 CREATE 作業,因此此呼叫將成功。Had Jim Silva - 不在組織單位 example.com 或群組 AdminGrp (仍然不存在) 中 - 其憑證已作為最後一個引數傳送,呼叫會失敗,因為他沒有適當的權限。此呼叫會建立一個名為 "AdminGrp" 的新群組,其群組的初始成員為 jill.muller@example.com 和 ivan.novak@example.com,或具有屬性 (ABAC) role=admin 的任何人。

建立新資源

import "chaincodeACL"
...
{

  ...
  **newResource**  :=  **chaincodeACL**.Resource{

      "transferMarble", // Name of resource to create

      "The transferMarble chaincode function", // Description of the resource

      []string{"AllowAdmins"}, // Single ACL for now allowing admins

  }

  **resourceMgr**  :=  **chaincodeACL**.NewResourceManager(nil, stub)  // Not specify identity, use caller's identity as default.
  err :=  **resourceMgr**.Create(resourceMgr, nil)   // Using caller's certificate

  ...
}

這會建立一個名為 transferMarble 的新資源,應用程式可用來控制對 transferMarble 鏈碼函數的存取。目前僅限 AllowAdmins 存取控制清單存取。

檢查資源的存取權

我們可以在鏈碼中使用此新資源,只允許管理員透過修改 Marble 鏈碼的 invoke() 方法來傳輸大理石,如下所示:

import "chaincodeACL"
…
func (t \*SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {

  **resourceMgr**  :=  **chaincodeACL**.NewResourceManager(nil, stub)   // Not specify identity, use caller's identity as default.

  function, args := stub.GetFunctionAndParameters()

  fmt.Println("invoke is running " + function)        // Handle different functions

  if function == "initMarble" {   //create a new marble

      return t.initMarble(stub, args)}

  else if function == " **transferMarble**" { //change owner of a specific marble

    **allowed** , err : =  **resourceMgr**. **CheckAccess** ("transferMarble", "UPDATE", nil)
    if  **allowed**  == true {

      return t.transferMarble(stub, args)

    else {

      return NOACCESS

    }

    } else if function == "transferMarblesBasedOnColor" { //transfer all marbles of a certain color
    …

    }

}