Estoy tratando de entender la compensación inherente entre roles y permisos cuando se trata de control de acceso (autorización).
Comencemos con un hecho: en nuestro sistema, un Permiso será una unidad de acceso específica (" Editar recurso X ", " Acceder a la página del tablero ", etc.). Un Rol será una colección de 1+ Permisos. Un usuario puede tener 1+ Roles. Todas estas relaciones (usuarios, roles, permisos) se almacenan en una base de datos y se pueden cambiar sobre la marcha y según sea necesario.
Mis preocupaciones:
(1) ¿Qué tiene de malo "comprobar los roles para el control de acceso? ¿Qué beneficios se obtienen al verificar los permisos? En otras palabras, ¿cuál es la diferencia entre estos dos fragmentos a continuación:
if(SecurityUtils.hasRole(user)) {
// Grant them access to a feature
}
// vs.
if(SecurityUtils.hasPermission(user)) {
// Grant them access to a feature
}
Y:
(2) En este escenario, ¿qué valor útil proporcionan los roles? ¿No podríamos simplemente asignar 1+ Permisos a los Usuarios directamente? ¿Qué valor concreto de abstracción ofrecen los Roles (alguien puede dar ejemplos específicos)?
Respuestas:
En el momento de la comprobación, el código de llamada solo necesita saber "¿el usuario X tiene permiso para realizar la acción Y?" .
El código de llamada no le importa y no debe tener en cuenta las relaciones entre roles y permisos.
La capa de autorización verificará si el usuario tiene este permiso, generalmente verificando si el rol del usuario tiene este permiso. Esto le permite cambiar la lógica de autorización sin actualizar el código de llamada.
Si verifica directamente el rol en el sitio de la llamada, está formando implícitamente relaciones de permiso de rol and e inyectando lógica de autorización en el código de llamada, violando la separación de preocupaciones.
Si luego decide que ese rol
foo
no debe tener permisobaz
, debería cambiar cada código que verifica si el usuario es unfoo
.Los roles representan conceptualmente una colección con nombre de permisos.
Supongamos que está agregando una nueva función que permite al usuario editar ciertas configuraciones. Esta función debería estar disponible solo para administradores.
Si está almacenando permisos por usuario, tendría que encontrar todos los usuarios en su base de datos que de alguna manera sabe que son administradores (si no está almacenando información de roles para los usuarios, ¿cómo podría saber qué usuarios son administradores?) Y agregar este permiso a su lista de permisos.
Si usa roles, solo tiene que agregar el permiso al
Administrator
rol, que es más fácil de realizar, más eficiente en cuanto al espacio y menos propenso a errores.fuente
authorization layer
Probablemente no significa nada más que simplemente tener la definición de la función (es decir,user->hasPermission(SOME_PERMISSION)
verificar internamente los roles del usuario primero y luego verificar si alguno de los roles incluye / excluye el dado permiso. Por ejemplo,the calling code
podría estar verificando si una determinada página es visible para el usuario y llamaríauser->hasPermission(VIEW_GIVEN_PAGE)
, yauthorization layer
consiste en la definición de lahasPermission
función que verifica los roles como se indicó anteriormente.hasPermission
podría verificarusersRole.HasPermission(VIEW_GIVEN_PAGE) && !user.Suspended
. El punto es que todo se hace en un lugar y no en el código de consumo (llamada).En respuesta a su primera pregunta, el mayor problema con la comprobación de que un usuario tiene un rol en lugar de un permiso específico, es que los permisos pueden tener múltiples roles. Como ejemplo de esto, un desarrollador podría tener acceso para ver el portal del desarrollador en la intranet de la compañía, que probablemente también sea un permiso de su gerente. Si un usuario intenta acceder al portal del desarrollador, tendrá una verificación similar a:
(Una
switch
declaración en su idioma de elección sería mejor, pero aún no particularmente ordenada)Cuanto más común o más extendido sea un permiso, más roles de usuario necesitará verificar para asegurarse de que alguien pueda acceder a un sistema determinado. Esto también llevaría al problema de que cada vez que modifique los permisos para un rol, necesitaría modificar la verificación para reflejar esto. En un sistema grande, esto se volvería muy difícil de manejar muy rápidamente.
Si simplemente verifica que el usuario tiene el permiso que le permite acceder al portal del desarrollador, por ejemplo, no importa qué rol tenga, se le otorgará acceso.
Para responder a su segunda pregunta, la razón por la que tiene roles es porque actúan como fáciles de modificar y distribuir "paquetes" de permisos. Si tiene un sistema que tiene cientos de roles y miles de permisos, agregar un nuevo usuario (por ejemplo, un nuevo gerente de Recursos Humanos) requeriría que lo revise y les otorgue todos los permisos que tienen otros gerentes de Recursos Humanos. Esto no solo sería tedioso, sino que es propenso a errores si se hace manualmente. Compare esto con simplemente agregar el rol de "gerente de recursos humanos" al perfil de un usuario, lo que le otorgará el mismo acceso que cualquier otro usuario con ese rol.
Podría argumentar que podría simplemente clonar un usuario existente (si su sistema lo admite), pero si bien esto le otorga al usuario los permisos correctos para ese momento, puede ser posible que intente agregar o eliminar un permiso para todos los usuarios en el futuro. difícil. Un escenario de ejemplo para esto es si quizás en el pasado el personal de recursos humanos también estaba a cargo de la nómina, pero más tarde la compañía se vuelve lo suficientemente grande como para contratar personal específicamente para manejar la nómina. Esto significa que RR.HH. ya no necesita acceder al sistema de nómina, por lo que se puede eliminar el permiso. Si tiene 10 miembros diferentes de RR. HH., Deberá hacerlo manualmente y asegurarse de eliminar el permiso correcto que introduce la posibilidad de error del usuario. El otro problema con esto es que simplemente no escala; A medida que gana más y más usuarios en un rol determinado, la modificación de un rol es mucho más difícil. Compare esto con el uso de roles, donde solo necesitaría modificar el rol general en cuestión para eliminar el permiso, lo que sería reflejado por cada usuario que tenga ese rol.
fuente