Beispiel-Walkhough mit der fein granulierten Zugriffskontrollbibliothek

Dieses Thema enthält einige Beispiele für die Verwendung von Library und Chaincode. In diesen Beispielen wird davon ausgegangen, dass die Funktion Init() aufgerufen wurde, um die Bootstrap-Entitys zu erstellen, und dass der Aufrufer von Init() und invoke() "%CN%frank.thomas@example.com" ist. Der normale Ablauf in einer Anwendung besteht darin, einige anfängliche Access Control-Listen zu erstellen, die verwendet werden, um den Zugriff auf die anderen Entitys zu erteilen oder zu verweigern.

Initialisierung

Rufen Sie die Funktion Initialization() auf, um Bootstrap-Entitys beim Deployment von Chaincodes zu erstellen. Beispiel:

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

ACL erstellen

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 administrators 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)

}

Mit der neuen ACL können Sie ändern, wer bestimmte Vorgänge ausführen kann. Fügen Sie zunächst diese neue ACL zur Bootstrap-Gruppe .Groups hinzu, damit jeder Administrator eine Gruppe erstellen kann.

ACL zu Gruppe hinzufügen

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

)

}

Dadurch wird die AllowAdmins-ACL der Bootstrap-Gruppe .Groups nach der anfänglichen Bootstrap-ACL hinzugefügt. Dadurch wird sichergestellt, dass Frank Thomas weiterhin Vorgänge für die Gruppe .Groups abschließen kann, da die ACL, die Frank Berechtigung erteilt, an erster Stelle in der Liste steht. Jetzt kann jeder, der mit der ACL AllowAdmins übereinstimmt, die Vorgänge CREATE, READ, UPDATE oder DELETE abschließen (sie können jetzt Gruppen erstellen).

Gruppen erstellen

Administratoren können jetzt eine Gruppe erstellen.

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

...
}

Dieser Aufruf verwendet eine explizite Identität (Bob Garcia, indem er sein Zertifikat verwendet), um zu versuchen, eine Gruppe zu erstellen. Da Bob Garcia einem Muster in der AllowAdmins ACL entspricht und Mitglieder dieser ACL CREATE-Vorgänge für die Bootstrap-Gruppe .Groups ausführen können, ist dieser Aufruf erfolgreich. Hätte Jim Silva, der weder in der Organisationseinheit example.com noch in der Gruppe AdminGrp (die immer noch nicht existiert) war, sein Zertifikat als letztes Argument übergeben, würde der Aufruf fehlschlagen, da er nicht über die entsprechenden Berechtigungen verfügt. Dieser Aufruf erstellt eine Gruppe namens "AdminGrp", wobei die anfänglichen Mitglieder der Gruppe jill.muller@example.com und ivan.novak@example.com oder alle Mitglieder mit dem Attribut (ABAC) role=admin sind.

Ressource erstellen

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 administrators

  }

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

  ...
}
Dadurch wird eine Ressource mit dem Namen transferMarble erstellt, mit der die Anwendung den Zugriff auf die Chaincode-Funktion transferMarble steuern kann. Der Zugriff ist derzeit durch die Access Control-Liste AllowAdmins begrenzt.

Zugriff auf eine Ressource prüfen

Sie können diese neue Ressource in Ihrem Chaincode verwenden, damit nur Administratoren einen Marmor übertragen können, indem Sie die Methode invoke() des Marbles-Chaincodes ändern, wie im folgenden Code dargestellt:

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 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
    …

    }

}