Pregunta

A menudo me encuentro con el siguiente escenario en el que necesito ofrecer muchos tipos diferentes de permisos.Utilizo principalmente ASP.NET/VB.NET con SQL Server 2000.

Guión

Quiero ofrecer un sistema de permisos dinámico que pueda funcionar en diferentes parámetros.Digamos que quiero darle acceso a una aplicación a un departamento o simplemente a una persona específica.Y pretender que tenemos una cantidad de aplicaciones que sigue creciendo.

En el pasado, elegí una de las siguientes dos formas que conozco para hacer esto.

  1. Use una sola tabla de permiso con columnas especiales que se usen para determinar cómo aplicar los parámetros.Las columnas especiales en este ejemplo son typeId y typeauxid.El SQL se vería algo así.

    SELECT COUNT(PermissionID)
    FROM application_permissions
    WHERE
    (TypeID = 1 AND TypeAuxID = @UserID) OR
    (TypeID = 2 AND TypeAuxID = @DepartmentID)
    AND ApplicationID = 1
    
  2. Use una tabla de mapeo para cada tipo de permiso, luego unirlos todos juntos.

    SELECT COUNT(perm.PermissionID)
    FROM application_permissions perm
    LEFT JOIN application_UserPermissions emp
    ON perm.ApplicationID = emp.ApplicationID
    LEFT JOIN application_DepartmentPermissions dept
    ON perm.ApplicationID = dept.ApplicationID
    WHERE q.SectionID=@SectionID
      AND (emp.UserID=@UserID OR dept.DeptID=@DeptID OR
     (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
    ORDER BY q.QID ASC
    

Mis pensamientos

Espero que los ejemplos tengan sentido.Los improvisé.

El primer ejemplo requiere menos trabajo, pero ninguno de los dos parece la mejor respuesta.¿Existe una mejor manera de manejar esto?

¿Fue útil?

Solución

Estoy de acuerdo con John Downey.

Personalmente, a veces uso una enumeración marcada de permisos.De esta manera puede utilizar operaciones bit a bit AND, OR, NOT y XOR en los elementos de la enumeración.

"[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}"

Luego, puede combinar varios permisos utilizando el operador bit a bit AND.

Por ejemplo, si un usuario puede ver y editar usuarios, el resultado binario de la operación es 0000 0011, que convertido a decimal es 3.
Luego puede almacenar el permiso de un usuario en una sola columna de su base de datos (en nuestro caso serían 3).

Dentro de su aplicación, sólo necesita otra operación bit a bit (OR) para verificar si un usuario tiene un permiso particular o no.

Otros consejos

La forma en que suelo codificar sistemas de permisos es tener 6 tablas.

  • Usuarios: esto es bastante sencillo, es la tabla de usuarios típica.
  • Grupos: esto también sería aplicable a sus departamentos.
  • Roles: esta es una tabla con todos los permisos que generalmente también incluye un nombre legible por humanos y una descripción.
  • Users_have_Groups: esta es una tabla de muchos a muchos de los grupos a los que pertenece un usuario.
  • Users_have_Roles: otra tabla de muchos a muchos de los roles asignados a un usuario individual
  • Groups_have_Roles: la tabla final de muchos a muchos de los roles que tiene cada grupo.

Al comienzo de la sesión de un usuario, ejecutaría alguna lógica que extrae todos los roles que han asignado, ya sea por directorio o a través de un grupo.Luego codifica esos roles como sus permisos de seguridad.

Como dije, esto es lo que suelo hacer, pero su millaje puede variar.

Además de las soluciones de John Downey y jdecuyper, también agregué un bit de "Denegación explícita" al final/principio del campo de bits, para que pueda realizar permisos adicionales por grupo, membresía de rol y luego restar permisos según la denegación explícita. entradas, al igual que funciona NTFS, en cuanto a permisos.

Honestamente, las características de Membresía/Roles de ASP.NET funcionarían perfectamente para el escenario que usted describió.Escribir sus propias tablas/proces/clases es un gran ejercicio y puede obtener un control muy bueno sobre detalles minuciosos, pero después de hacerlo yo mismo, he llegado a la conclusión de que es mejor simplemente usar el material .NET integrado.Una gran cantidad de código existente está diseñado para solucionarlo, lo cual también es bueno.Escribir desde cero me llevó aproximadamente 2 semanas y no era tan sólido como .NET.Tienes que codificar tanta basura (recuperación de contraseña, bloqueo automático, cifrado, roles, una interfaz de permisos, toneladas de procesos, etc.) y sería mejor invertir el tiempo en otra cosa.

Lo siento si no respondí tu pregunta, soy como el tipo que dice que aprendas C# cuando alguien hace una pregunta sobre vb.

Un enfoque que he usado en varias aplicaciones es tener una clase PermissionToken genérica que tenga una propiedad Value modificable.Luego consulta la aplicación solicitada, le indica qué PermissionTokens se necesitan para poder usarla.

Por ejemplo, la aplicación Envío podría indicarle que necesita:

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

Obviamente, esto se puede extender a Crear, Editar, Eliminar, etc. y, debido a la propiedad Valor personalizada, cualquier aplicación, módulo o widget puede definir sus propios permisos requeridos.YMMV, pero este siempre ha sido un método eficiente para mí y he descubierto que escala bien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top