Beispiel für die Verwendung der Bibliothek für fein granulierte Zugriffskontrolle

Dieses Thema enthält einige Beispiele für die Verwendung dieser Library und dieses Chaincodes. Diese alle unter der Annahme, dass Init() aufgerufen wurde, um die Bootstrap-Entitys zu erstellen, und der Aufrufer von Init() und invoke() lautet "%CN%frank.thomas@example.com". Der normale Ablauf in einer Anwendung besteht darin, einige anfängliche Access Control-Listen zu erstellen, mit denen der Zugriff auf die anderen Entitys erteilt oder verweigert wird.

Initialisierung

Rufen Sie Initialization() auf, um Bootstrap-Entitys bei der Instanziierung von Chaincode 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 Vorgänge ausführen kann. Daher fügen wir diese neue ACL zuerst der 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 nach der anfänglichen Bootstrap-ACL zur Bootstrap-Gruppe .Groups hinzugefügt. Dadurch wird sichergestellt, dass Frank Thomas weiterhin Vorgänge auf .Groups ausführen kann, da die ACL, die ihm die Berechtigung erteilt, an erster Stelle in der Liste steht. Aber jetzt kann jeder, der mit der ACL AllowAdmins übereinstimmt, CREATE-, READ-, UPDATE- oder DELETE-Vorgänge ausführen (sie können jetzt neue Gruppen erstellen).

Neue Gruppen erstellen

Admins 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 ACL AllowAdmins 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 scheitern, 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 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 kontrollieren kann. Der Zugriff wird derzeit durch die Access-Control-Liste AllowAdmins eingeschränkt.

Zugriff auf eine Ressource überprü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-Kettencodes 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
    …

    }

}