Beispiel-Walkthough mit der Fine-Grained Access Control Library

Dieses Thema enthält einige Beispiele für die Verwendung dieser Bibliothek und dieses Chaincodes. Diese alle gehen davon aus, dass 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 Zugriffskontrolllisten zu erstellen, mit denen der Zugriff auf die anderen Entitys erteilt oder verweigert wird.

Initialisierung

Rufen Sie Initialization() auf, um beim Instanziieren von chaincode Bootstrap-Entitys zu erstellen. Beispiel:

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

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

}

Jetzt, da wir eine neue ACL haben, können wir diese verwenden, um zu ändern, wer bestimmte Operationen ausführen kann. Daher fügen wir diese neue ACL zuerst der Bootstrap-Gruppe .Groups hinzu, damit jeder Administrator eine Gruppe erstellen kann.

Hinzufügen einer ACL zu einer Gruppe

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 Operationen an .Groups ausführen kann, da die ACL, die ihm die Berechtigung erteilt, an erster Stelle in der Liste steht. Aber jetzt kann jeder, der der AllowAdmins ACL entspricht, CREATE-, READ-, UPDATE- oder DELETE-Vorgänge ausführen (sie können jetzt neue Gruppen erstellen).

Erstellen Sie eine neue Gruppe

Administratoren können jetzt eine neue 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 - die von Bob Garcia (mit seinem Zertifikat), um zu versuchen, eine neue 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äre der Aufruf nicht erfolgreich, da er nicht über die entsprechenden Berechtigungen verfügt. Dieser Aufruf erstellt eine neue Gruppe namens "AdminGrp", wobei die ersten Mitglieder der Gruppe jill.muller@example.com und ivan.novak@example.com oder alle Mitglieder mit dem Attribut (ABAC) role=admin sind.

Neue 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 admins

  }

  **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 neue Ressource namens 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

Wir können diese neue Ressource in unserem Chaincode verwenden, um Administratoren nur die Übertragung eines Marmors zu ermöglichen, indem wir die Methode invoke() des Marbles-Chaincodes wie folgt ändern:

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
    …

    }

}