Ejemplo de revisión mediante la biblioteca de control de acceso detallado
En este tema, se proporcionan algunos ejemplos de cómo se pueden utilizar esta biblioteca y este código de cadenas. Se ha llamado a Init()
para crear las entidades de inicialización de datos y el emisor de llamada de Init()
y invoke()
es "%CN%frank.thomas@example.com"
. El flujo normal en una aplicación será crear algunas listas de control de acceso iniciales que se utilizarán para otorgar o denegar el acceso a otras entidades.
Inicialización
Llame a Initialization()
para crear entidades de inicialización al instanciar el código de cadenas. Por ejemplo:
import "chaincodeACL"
func (t \*SimpleChaincode) Init(nil, stub shim.ChaincodeStubInterface) pb.Response
{
err := chaincodeACL.Initialization(stub)
}
Crear Nueva 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)
}
Ahora que tenemos una nueva ACL, podemos utilizarla para modificar quién puede realizar determinadas operaciones. Por lo tanto, primero agregaremos esta nueva ACL al grupo de inicialización de datos .Groups
para permitir que cualquier administrador cree un grupo.
Agregar una ACL a un grupo
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
)
}
Esto agrega la ACL AllowAdmins
al grupo de inicialización de datos .Groups
después de la ACL de inicialización de datos inicial. Por lo tanto, esto garantiza que Frank Thomas todavía pueda realizar operaciones en .Groups
, ya que la ACL que le otorga permiso es la primera en la lista. Pero ahora cualquier persona que coincida con la ACL AllowAdmins
puede realizar las operaciones CREATE, READ, UPDATE o DELETE (ahora puede crear nuevos grupos).
Cree un grupo nuevo
Los administradores ahora pueden crear un nuevo grupo:
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
...
}
Esta llamada está utilizando una identidad explícita - la de Bob García (usando su certificado) - para intentar crear un nuevo grupo. Dado que Bob García coincide con un patrón en la ACL AllowAdmins
y que los miembros de esa ACL pueden realizar operaciones CREATE en el grupo de inicialización de datos .Groups
, esta llamada se realizará correctamente. Si Jim Silva, que no estaba en la unidad de organización example.com
ni en el grupo AdminGrp
(que aún no existe), hubiera aprobado su certificado como último argumento, la llamada fallaría porque no tiene los permisos adecuados. Esta llamada creará un nuevo grupo denominado "AdminGrp
" y los miembros iniciales del grupo serán jill.muller@example.com y ivan.novak@example.com, o cualquier persona con el atributo (ABAC) role=admin.
Crear nuevo recurso
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
...
}
Esto crearía un nuevo recurso denominado transferMarble
que la aplicación podría utilizar para controlar el acceso a la función de código de cadenas transferMarble
. Actualmente, el acceso está limitado por la lista de control de acceso AllowAdmins
.
Comprobación del acceso a un recurso
Podemos utilizar este nuevo recurso en nuestro código de cadenas para permitir solo a los administradores transferir un mármol modificando el método invoke()
del código de cadenas Marbles de la siguiente forma:
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
…
}
}