Exemple d'utilisation de la bibliothèque de contrôle d'accès de niveau fin

Cette rubrique fournit des exemples d'utilisation de la bibliothèque et du code de chaîne. Ces exemples supposent tous que la fonction Init() a été appelée pour créer les entités d'amorçage et que l'appelant de Init() et invoke() est "%CN%frank.thomas@example.com". Le flux normal dans une application consiste à créer des listes de contrôle d'accès initiales qui seront utilisées pour accorder ou refuser l'accès aux autres entités.

Initialisation

Appelez la fonction Initialization() pour créer des entités d'amorçage lors du déploiement de codes de chaîne. Par exemple :

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

Créer une liste de contrôle d'accès

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)

}

Vous pouvez utiliser la nouvelle liste de contrôle d'accès pour modifier qui peut effectuer certaines opérations. Tout d'abord, ajoutez cette nouvelle liste de contrôle d'accès au groupe d'amorçage .Groups pour permettre à tout administrateur de créer un groupe.

Ajouter une liste de contrôle d'accès à un groupe

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

)

}

Cela ajoute la liste de contrôle d'accès AllowAdmins au groupe d'amorçage .Groups après la liste de contrôle d'accès d'amorçage initiale. Ainsi, Frank Thomas peut toujours effectuer des opérations sur le groupe .Groups, car la liste de contrôle d'accès qui accorde l'autorisation Frank figure en premier dans la liste. Maintenant, toute personne qui correspond à la liste de contrôle d'accès AllowAdmins peut effectuer les opérations CREATE, READ, UPDATE ou DELETE (elle peut maintenant créer des groupes).

Créer un groupe

Les administrateurs peuvent maintenant créer un groupe.

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

...
}

Cet appel utilise une identité explicite (Bob Garcia, en utilisant son certificat) pour tenter de créer un groupe. Comme Bob Garcia correspond à un modèle dans la liste de contrôle d'accès AllowAdmins et que les membres de cette liste de contrôle d'accès peuvent effectuer des opérations CREATE sur le groupe d'amorçage .Groups, cet appel réussira. Si Jim Silva, qui n'était pas dans l'unité organisationnelle example.com ni dans le groupe AdminGrp (qui n'existe toujours pas), avait son certificat transmis comme dernier argument, l'appel échouerait car il n'a pas les autorisations appropriées. Cet appel crée un groupe nommé "AdminGrp" dont les membres initiaux sont jill.muller@example.com et ivan.novak@example.com ou toute personne ayant l'attribut (ABAC) role=admin.

Créer une ressource

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

  ...
}
Cela crée une ressource nommée transferMarble que l'application peut utiliser pour contrôler l'accès à la fonction de code de chaîne transferMarble. L'accès est actuellement limité par la liste de contrôle d'accès AllowAdmins.

Vérifier l'accès pour une ressource

Vous pouvez utiliser cette nouvelle ressource dans votre code de chaîne pour permettre uniquement aux administrateurs de transférer une marbre, en modifiant la méthode invoke() du code de chaîne Marbres, comme indiqué dans le code suivant :

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
    …

    }

}