database-design - para - manual de programacion android pdf
¿Cuál es la mejor forma de administrar permisos para una aplicación web, una máscara de bits o una tabla de base de datos? (8)
¿Qué hay de crear una tabla de Permiso, luego una tabla de Permisión de Usuario para almacenar las relaciones?
Nunca más tendrá que modificar la estructura y podrá agregar tantos permisos como desee.
Estoy considerando la mejor manera de diseñar un sistema de permisos para una aplicación web "admin". Es probable que la aplicación tenga muchos usuarios, a cada uno de los cuales se le podría asignar un determinado rol; a algunos de estos usuarios se les podría permitir realizar tareas específicas fuera del rol.
Se me ocurren dos formas de diseñar esto: uno, con una tabla de "permisos" con una fila para cada usuario y columnas booleanas, una para cada tarea, que les asigna permisos para realizar esas tareas. Me gusta esto:
User ID Manage Users Manage Products Manage Promotions Manage Orders 1 true true true true 2 false true true true 3 false false false true
Otra forma en que pensé fue utilizar una máscara de bits para almacenar estos permisos de usuario. Esto limitaría el número de tareas que se podrían administrar a 31 para un entero de 32 bits con signo, pero en la práctica es poco probable que tengamos más de 31 tareas específicas que un usuario podría realizar. De esta forma, el esquema de la base de datos sería más simple, y no tendríamos que cambiar la estructura de la tabla cada vez que agregamos una nueva tarea que necesitaría control de acceso. Me gusta esto:
User ID Permissions (8-bit mask), would be ints in table 1 00001111 2 00000111 3 00000001
¿Qué mecanismos han usado típicamente las personas aquí, y por qué?
¡Gracias!
Creo que es una regla general evitar los bitstrings místicos que codifican el significado del universo.
Aunque quizás sea más raro, tener una tabla de posibles permisos, una tabla de usuarios y una tabla de enlaces entre ellos es la mejor y más clara manera de organizar esto. También hace que sus consultas y mantenimiento (especialmente para el nuevo tipo) sean mucho más fáciles.
He visto varios sistemas de permisos algo limitados similares a los que está sugiriendo, así como algunos sistemas realmente terribles. En algunas situaciones simples, pueden ser aceptables, siempre que la aplicación no se vuelva más compleja. Sin embargo, en muchos casos, se vuelven más complicados y los sistemas deben reescribirse para adaptarse a la funcionalidad requerida.
Si crees que algún día necesitarás la expresividad, iría con un sistema completo de ACL (lista de control de acceso) con usuarios y grupos (o roles). Es decir, cada cosa gobernada por permisos (por ejemplo, "administrar usuarios", "administrar productos") tiene una ACL, que es una lista de todos los usuarios y grupos que tienen acceso a ella. Luego, los usuarios se agregan directamente a las ACL relevantes o se agregan a un grupo que ya es miembro de una ACL.
A pesar de que ACL sugiere una implementación de lista, sería mejor que tuvieras una mesa; esta respuesta es una buena manera.
Lo hice de las dos maneras. Pero ya no uso máscaras de bits. Una tabla separada estaría bien que puede usar como una referencia cruzada, dado un id de usuario o una identificación de grupo como una clave foránea.
UserID | Permission
===================
1 | 1 1 representing manage users
1 | 2 2 being manger products
2 | 3
De esta manera sería más fácil de mantener y agregar más adelante.
También usaría una tabla separada para administrar cuáles son los permisos.
PermissionID | Description
==========================
1 | Manage Users
2 | Manager Products
Los permisos generalmente son palabras clave con un 1, 0 o nulo (que indican heredar). Con un sistema de bits, probablemente no pueda crear índices en la identificación del usuario y la palabra clave de permiso; en su lugar, tendría que escanear cada registro para obtener el valor de permiso.
Yo diría que ir por la primera opción. Me parece la mejor solución:
create table permissions (
user_id INT NOT Null,
permission VARCHAR(255) NOT NULL,
value TINYINT(1) NULL
)
alter table `permissions` ADD PRIMARY KEY ( `user_id` , `permission` )
Puede usar Active Directory u otra implementación de LDAP si se encuentra en un entorno administrado. De esta forma, los grupos de seguridad, que determinan los permisos, pueden ser gestionados por el soporte de primera línea, utilizando una tecnología con la que probablemente ya estén familiarizados.
Si su aplicación está empaquetada, entonces +1 para la sugerencia de Levi Rosol de normalizar la base de datos para que pueda tener un modelo de datos extensible en su aplicación.
Sugiero que resuma sus permisos de aplicación web con el concepto de Proveedor de funciones. A partir de la versión 2.0, esto se proporciona para usted en .NET como System.Web.Security.RoleProvider .
La idea básica es aprovechar un marco existente al escribir sus comprobaciones de permisos contra el marco en lugar de un mecanismo de almacenamiento específico. A continuación, puede conectar cualquier mecanismo de almacenamiento disponible, ya sea un archivo XML, una base de datos o incluso un almacén de autorizaciones utilizando el Administrador de autorizaciones de software de Windows (que le permite vincular sin problemas sus permisos personalizados a LDAP, por ejemplo, no código requerido para configurar)
Si decide usar una base de datos como mecanismo de almacenamiento, se admiten varias bases de datos para la creación automática de las tablas subyacentes que necesita el marco. Esto incluye ejecutar .NET en Mono y usar el modelo de proveedor de roles sobre MySQL.
Consulte Implementación de un proveedor de funciones para obtener más información. Es muy posible que otros lenguajes / entornos también tengan bibliotecas que pueda aprovechar para implementar este concepto, vale la pena investigarlo.
EDITAR : También debo señalar que la configuración de cómo su aplicación web se relaciona con el mecanismo de almacenamiento se realiza a través de un archivo web.config y no requiere cambios de código. Encontré esto muy útil para probar una versión de producción de una base de código en mi máquina local, usando un archivo XML para imitar permisos en lugar del proveedor de base de datos normal, todo modificando dos líneas en web.config.
La otra cosa que olvidé mencionar es que puedes conectar tus propios proveedores personalizados ampliando las clases base, lo que te permite aprovechar el modelo de permisos pero aún así usar un sistema de almacenamiento patentado (por ejemplo, máscaras de bits, si realmente lo deseas) .
Usualmente tengo una tabla de Usuarios, una tabla de Roles y una tabla de UserRoles. De esta forma, puede tener una cantidad ilimitada de roles sin cambiar su estructura de db y los usuarios pueden tener múltiples roles.
Forzo la aplicación para que solo autorice contra roles (nunca usuarios). Observe cómo la columna "id" en la tabla de roles no es una columna de identidad. Esto se debe a que es posible que deba controlar los ID que se colocan en esta tabla porque su aplicación tendrá que buscar ID específicos.
La estructura se ve así:
create table Users (
id int identity not null,
loginId varchar(30) not null,
firstName varchar(50) not null,
etc...
)
create table Roles (
id int not null,
name varchar(50) not null
)
create table UserRoles (
userId int not null,
roleId int not null
)