Control de acceso basado en roles

[size="7"]Control de acceso basado en roles[/size]

[size="7"](Role-Based Access Control - RBAC)[/size]

El control de acceso basado en roles proporciona un control de acceso centralizado simple pero potente.

Yii implementa un esquema jerárquico de RBAC a través del componente AuthManager. A continuación nos introduciremos en los principales conceptos utilizados en este esquema, seguidamente describiremos cómo definir los datos de autorización, y finalmente mostraremos cómo hacer uso de los datos de autorización para realizar la comprobación de acceso.

[size="5"]Introducción[/size]

Un concepto fundamental en el RBAC de Yii es elemento de autorización. Un elemento de autorización es un permiso para hacer algo (por ejemplo, la creación de entradas en blogs, gestión de usuarios). De acuerdo a su granularidad y al público objetivo, los elementos de autorización pueden ser clasificados como operaciones, tareas y roles. Un rol consiste de tareas, una tarea consiste de operaciones, y una operación es un permiso que es unitario. Por ejemplo, podemos tener un sistema con rol de administrador, que consiste en tareas de gestión de entradas y tareas de administración de usuarios. La tarea de gestión de usuarios puede consistir en las operaciones de creación, modificación y eliminación de usuarios. Para mayor flexibilidad, Yii también permite que un rol consista de otros roles u operaciones, que las tareas consistan de otras tareas, y que una operación consista de otras operaciones.

Un elemento de autorización se identifica por su nombre.

Un elemento de autorización puede estar asociado a una regla de negocio. Una regla de negocio es una parte de código PHP que se ejecutará cuando el acceso necesite ser comprobado con respecto al elemento de autorización. Sólo cuando la ejecución de la regla de negocio devuelva True, el usuario será considerado autorizado representado por el elemento de autorización. Por ejemplo, al definir una operación updatePost, nos gustaría añadir una regla de negocio que compruebe si el ID del usuario es el mismo que el ID del usuario que creó la entrada, para que sólo el autor pueda tener permisos para actualizar la entrada.

Utilizando los elementos de autorización, podemos construir una jerarquía de autorización. Un elemento A es padre de otro elemento B en la jerarquía si A está formado por B (o decir que A hereda los permisos representados por B ). Un elemento puede tener varios elementos hijos, y también puede tener múltiples elementos padre. Por lo tanto, una jerarquía de autorización es un gráfico de orden parcial en lugar de un árbol jerárquico. En esta jerarquía, los roles se sitúan en la parte más alta, las operaciones ocupan los niveles inferiores, mientras que las tareas se encuentran entre los anteriores elementos.

Una vez que tengamos una jerarquía de autorización, podremos asignar roles en esta jerarquía a los usuarios de la aplicación. Un usuario, un vez asignado un rol, tendrá los permisos representados por dicho rol. Por ejemplo, si asignamos el rol de administrador a un usuario, él tendrá los permisos de administrador que incluyen gestión de entradas y gestión de usuarios (y las correspondientes operaciones, tales como crear usuarios).

Ahora empieza la parte divertida. En una acción de controlador, queremos comprobar si el usuario actual puede eliminar la entrada específica. Usando la jerarquía y la asignación de RBAC, esto se puede hacer fácilmente de la siguiente manera:


if(Yii::app()->user->checkAccess('deletePost'))

{

    // eliminar la entrada

}

[size="5"]Configuración del administrador de autorización[/size]

Antes de ponernos en marcha con la definición de la jerarquía de autorización y con la comprobación de acceso, tendremos que configurar el componente AuthManager. Yii proporciona dos tipos de gestores de autorización: CPhpAuthManager y CDbAuthManager. El primero utiliza un script PHP para almacenar los datos de autorización, mientras que el segundo almacena los datos en una base de datos. Cuando configuremos el componente AuthManager, tendremos que especificar qué clase del componente vamos a utilizar, así como los valores iniciales de sus propiedades. Por ejemplo:


return array(

    'components'=>array(

        'db'=>array(

            'class'=>'CDbConnection',

            'connectionString'=>'sqlite:path/to/file.db',

        ),

        'authManager'=>array(

            'class'=>'CDbAuthManager',

            'connectionID'=>'db',

        ),

    ),

);

Entonces podremos acceder al componente AuthManager usando Yii::app()->authManager

[size="5"]Definiendo la jerarquía de autorización[/size]

La definición de la jerarquía de autorización implica tres pasos: la definición de elementos de autorización, el establecimiento de relaciones entre los elementos de autorización, y la asignación de los roles a los usuarios de la aplicación. El componente AuthManager proporciona una API completa para realizar estas tareas.

Para definir un elemento de autorización, utilice uno de los siguientes métodos, dependiendo del tipo de elemento:

  • CAuthManager::createRole

  • CAuthManager::createTask

  • CAuthManager::createOperation

Una vez tengamos un conjunto de elementos de autorización, podremos utilizar los siguientes métodos para establecer relaciones entre los elementos de autorización:

  • CAuthManager::addItemChild

  • CAuthManager::removeItemChild

  • CAuthItem::addChild

  • CAuthItem::removeChild

Y finalmente, podremos llamar a los siguientes métodos para asignar los roles a los usuarios individualmente:

  • CAuthManager::assign

  • CAuthManager::revoke

A continuación mostramos un ejemplo sobre la construcción de una jerarquía de autorización con la API proporcionada:


$auth=Yii::app()->authManager;

 

$auth->createOperation('createPost','create a post');

$auth->createOperation('readPost','read a post');

$auth->createOperation('updatePost','update a post');

$auth->createOperation('deletePost','delete a post');

 

$bizRule='return Yii::app()->user->id==$params["post"]->authID;';

$task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);

$task->addChild('updatePost');

 

$role=$auth->createRole('reader');

$role->addChild('readPost');

 

$role=$auth->createRole('author');

$role->addChild('reader');

$role->addChild('createPost');

$role->addChild('updateOwnPost');

 

$role=$auth->createRole('editor');

$role->addChild('reader');

$role->addChild('updatePost');

 

$role=$auth->createRole('admin');

$role->addChild('editor');

$role->addChild('author');

$role->addChild('deletePost');

 

$auth->assign('reader','readerA');

$auth->assign('author','authorB');

$auth->assign('editor','editorC');

$auth->assign('admin','adminD');

Una vez que hayamos establecido esta jerarquía, el componente AuthManager (por ejemplo CPhpAuthManager o CDbAuthManager) cargará automáticamente los elementos de autorización. Por lo tanto, sólo tendremos que ejecutar el código anterior una vez, y NO para cada solicitud.

Información: Aunque el ejemplo anterior se ve largo y tedioso, es principalmente para fines demostrativos. Los desarrolladores tendrán que desarrollar algunas interfaces gráficas para la administración de usuarios, para que los usuarios finales puedan establecer las jerarquías de autorización de forma más intuitiva.

[size="5"]Usando reglas de negocio[/size]

Cuando estamos definiendo la jerarquía de autorización, se puede asociar un rol, una tarea o una operación con una llamada a una regla de negocio. Podemos también asociar una regla de negocio cuando asignemos un rol a un usuario. Una regla de negocio es una porción de código PHP que se ejecuta cuando llevamos a cabo la comprobación de acceso. El valor devuelto por la regla de negocio se utiliza para determinar si el rol o asignación se aplica al usuario actual. En el ejemplo siguiente, asociamos una regla de negocio con la tarea updateOwnPost. En la regla de negocio simplemente comprobamos si el ID del usuario actual es el mismo que el ID del autor de la entrada especifica. La información de la entrada en la matriz $param es suministrado por los desarrolladores cuando se realiza la comprobación de acceso.


$params=array('post'=>$post);

if(Yii::app()->user->checkAccess('updateOwnPost',$params))

{

    // editar entrada

}

[size="5"]Comprobación de acceso[/size]

Para realizar la comprobación de acceso, primero tenemos que conocer el nombre del elemento de autorización. Por ejemplo, para comprobar si el usuario actual puede crear una entrada, deberemos comprobar si tiene el permiso representado por la operación createPost. Entonces llamaremos a CWebUser::checkAccess para realizar la comprobación de acceso.


if(Yii::app()->user->checkAccess('createPost'))

{

    // crear entrada

}

Si la regla de autorización se asocia a una regla de negocio que requiere parámetros adicionales, podemos pasarlos también. Por ejemplo, para comprobar si un usuario puede editar una entrada, pasaríamos los datos de la entrada como parámetros ($params).


$params=array('post'=>$post);

if(Yii::app()->user->checkAccess('updateOwnPost',$params))

{

    // editar entrada

}

[size="5"]Usando roles por defecto[/size]

Nota: La característica de roles por defecto está disponible desde la versión 1.0.3

Muchas aplicaciones Web necesitan algunos roles muy especiales que serán asignados a todos o a muchos de los usuarios del sistema. Por ejemplo, es posible que desee asignar algunos privilegios a todos los usuarios autenticados. Esto plantearía muchos problemas de mantenimiento si se especifican explícitamente y se almacenan estas asignaciones de roles. Podemos aprovechar los roles por defecto para resolver estos problemas.

Un rol por defecto es un rol que se asigna implícitamente para todos los usuarios, incluyendo autenticados e invitados. No es necesario que se le aplique expresamente a un usuario. Cuando llamamos a CWebUser::checkAccess, los roles por defecto son comprobados primeramente como si estuvieran asignados a usuarios.

Los roles por defecto deben ser declarados en las propiedades de CAuthManager::defaultRoles. Por ejemplo, la siguiente configuración declara dos roles como roles por defecto: autenticados e invitados.


return array(

    'components'=>array(

        'authManager'=>array(

            'class'=>'CDbAuthManager',

            'defaultRoles'=>array('authenticated', 'guest'),

        ),

    ),

);

Debido a que un rol por defecto se asigna a todos los usuarios, por lo general tiene que estar asociado a una regla de negocio que determina si el rol se aplica realmente al usuario. Por ejemplo, el siguiente código define dos roles, autenticado e invitado, lo que efectivamente se aplican a los usuarios autenticados e invitados, respectivamente.


$bizRule='return !Yii::app()->user->isGuest;';

$auth->createRole('authenticated', 'authenticated user', $bizRule);

 

$bizRule='return Yii::app()->user->isGuest;';

$auth->createRole('guest', 'guest user', $bizRule);


Cuando tenga más material lo ire posteando.

Saludos.

Hola Juan!!

Gracias por compartir esto!!

Si querés podés pedir acceso al SVN de YiiDoc desde el siguiente topic: ([size=2]http://www.yiiframework.com/forum/index.php?/topic/467-call-for-help-yii-internationalization/page__hl__yiidoc)[/size]

Saludos y gracias,

Sebas

http://code.google.com/p/yiidoc/

Hola buenas, soy nuevo en Yii, y a pesar de que he leido bastante el foro, este es mi primer post, todavía no me he puesto a probar esto del RBAC, antes de eso queria preguntar una cosa: ¿Es posible con este sistema, controlar las acciones que un usuario puede realizar sobre un formulario? Me explicaré mejor con un ejemplo:

Tengo tres roles: administrador --> puede realizar toda operación

              editor        --> puede usar todos los campos de un formulario excepto el boton "borrar"


              invitado      --> solo puede ver el formulario pero sin poder tocar ningun elemento (estan


                                 readonly)

Por lo tanto si entro como administrador veo un formulario donde puedo modificar todos los campos, guardar los cambios y eliminar, si entro como editor, podre modificar campos pero el boton eliminar no me aparecerá o estará inhabilitado.

Espero haberme explicado bien, gracias y un saludo.

s0mk3t.

Hola que tal soy novato en el uso de frameworks, he estado leyendo la guia y el libro de yii resulta que me quedé en medio camino pues trato de usar rbac con postgres.

Mi problema está en que estoy trabajando con esquemas de postgres y no sé como decirle a Yii que las tablas del rbac estan en algún esquema particular.

Creando las tablas en el esquema por defecto (default) si funciona pero necesito que esté en otro. Alguien sabe algo al respecto … agradeceria cualquier ayuda.

Gracias.