Solución:
Intentaré mostrar cómo puede beneficiarse del control de acceso basado en reclamos en un contexto ASP.NET MVC.
Cuando utiliza la autenticación basada en roles, si tiene una acción para crear un cliente y desea que las personas que están en el rol de ‘Venta’ puedan hacerlo, escriba un código como este:
[Authorize(Roles="Sale")]
public ActionResult CreateCustomer()
{
return View();
}
Más tarde, se dio cuenta de que, a veces, las personas del rol de ‘Marketing’ deberían poder crear un Cliente. Luego, actualizas tu método de acción así
[Authorize(Roles = "Sale", "Marketing")]
public ActionResult CreateCustomer()
{
return View();
}
Ahora, se dio cuenta de que algunas de las personas de marketing no deben poder crear un cliente, pero no es posible asignar un rol diferente para las personas que están en marketing. Por lo tanto, está obligado a permitir que toda la gente de marketing cree Clientes.
usted detectó otro problema, cada vez que decida que el personal de marketing debe poder crear clientes, debe actualizar todos los atributos de autorización de los métodos de acción de MVC, compilar su aplicación, probar e implementar. Unos días después, decidió que no se debería permitir el marketing sino algún otro rol para hacer la tarea, por lo que busca en su base de código y borra todo ‘Marketing’ del atributo Autorizar y agrega su nuevo nombre de rol en el atributo Autorizar … No es un solución saludable. En ese momento, se dará cuenta de la necesidad de un control de acceso basado en permisos.
El control de acceso basado en permisos es una forma de asignar varios permisos a varios usuarios y verificar si un usuario tiene permiso para ejecutar una acción desde el código en tiempo de ejecución. Después de asignar varios permisos a varios usuarios, se da cuenta de que necesita permitir que algunos usuarios ejecuten algún código si el usuario tiene alguna propiedad como “Usuario de Facebook”, “Usuario de mucho tiempo”, etc. Permítanme darles un ejemplo. Supongamos que desea permitir el acceso a una página específica si el usuario inició sesión con Facebook. Ahora, ¿crearía un permiso ‘Facebook’ para ese usuario? No, ‘Facebook’ no parece un permiso. Lo hace ? Más bien suena como un reclamo. Al mismo tiempo, los permisos también pueden sonar como un reclamo. Por lo tanto, es mejor verificar las reclamaciones y permitir el acceso.
Ahora, volvamos al ejemplo concreto del control de acceso basado en reclamos.
Puede definir un conjunto de reclamos como este:
“CanCreateCustomer”, “CanDeleteCustomer”, “CanEditCustomer”, etc.
Ahora, puedes decorar tu método de acción de esta manera:
[ClaimAuthorize(Permission="CanCreateCustomer")]
public ActionResult CreateCustomer()
{
return View();
}
(tenga en cuenta, [ClaimAuthorize(Permission=”CanCreateCustomer”)] puede no estar integrado en la biblioteca de clases MVC, solo lo muestro como un ejemplo, puede usar alguna biblioteca de clases que tenga dicha definición de clase de atributo)
Ahora, puede ver que el método de acción CreateCustomer siempre necesitará el permiso ‘CanCreateCustomer’ y nunca cambiará o apenas cambiará. Entonces, en su base de datos, crea una tabla de permisos (reclamos) y relación usuario-permiso. Desde su panel de administración, puede establecer permisos (reclamos) para cada usuario que puede hacer qué. Puede asignar el permiso ‘CanCreateCustomer’ (reclamo) a cualquier persona que desee y solo el usuario autorizado podrá crear un cliente y el usuario autorizado podrá crear solo un cliente y nada más (a menos que asigne otros permisos al mismo usuario).
Este modelo de seguridad le ofrece una práctica de código limpia. Además, cuando escribe su Método de acción, no tiene que pensar en quién puede usar este método, sino que siempre puede estar seguro de que quien esté usando este método tendrá el permiso (reclamo) adecuado otorgado por el Administrador. Luego, el administrador puede decidir quién podrá hacer qué. No tú como desarrollador. Así es como su lógica empresarial se separa de la lógica de seguridad.
Cada vez que alguien inicia sesión, su aplicación verificará los permisos disponibles para ese usuario y ese conjunto de permisos (reclamo) estará disponible como propiedades adicionales del usuario que ha iniciado sesión actualmente (por lo general, el conjunto de reclamos se almacena como cookie para el usuario que ha iniciado sesión). por lo que no tiene que verificar el conjunto de permisos todo el tiempo desde la base de datos. La conclusión es que obtiene más control de su lógica de seguridad en su aplicación si aplica acceso basado en reclamos en lugar de acceso basado en roles. De hecho, un rol también puede considerarse un reclamo.
Si su aplicación es una aplicación muy pequeña en la que solo habría 2 roles: Cliente y Administrador y no hay posibilidad de que el Cliente pueda hacer otra cosa que no sea lo que debe hacer en su aplicación, entonces quizás, Basado en roles El control de acceso cumplirá el propósito, pero a medida que su aplicación crezca, comenzará a sentir la necesidad de un control de acceso basado en reclamos en algún momento.
He implementado modelos de seguridad muchas veces y también he tenido que pensar en estos conceptos. Habiéndolo hecho muchas veces, aquí está mi comprensión de estos conceptos.
¿Qué son los roles?
Rol = El Unión de Usuarios y Permisos.
Por un lado, un rol es una colección de permisos. Me gusta llamarlo Perfil de permiso. Al definir un rol, básicamente agrega un montón de permisos a ese rol, por lo que, en ese sentido, un rol es un perfil de permisos.
Por otro lado, un rol también es una colección de usuarios. Si agrego a Bob y Alice al rol “Administradores”, entonces “Administradores” ahora contiene una colección de dos Usuarios como un grupo.
La verdad es que un Rol es TANTO una colección de Usuarios como una colección de Permisos juntos. Visualmente, esto se puede ver como un diagrama de Venn.
Que es un grupo
Grupo = Colección de usuarios
Un “Grupo” es estrictamente una colección de Usuarios. La diferencia entre un grupo y un rol es que un rol también tiene una colección de permisos, pero un grupo solo tiene una colección de usuarios.
¿Qué es un permiso?
Permiso = Qué puede hacer un sujeto
¿Qué es un conjunto de permisos?
Conjunto de permisos = una colección de permisos
En un sistema RBAC robusto, los permisos también se pueden agrupar como usuarios. Mientras que los grupos son solo una colección de usuarios, un conjunto de permisos es solo una colección de permisos. Esto permite que un administrador agregue colecciones completas de permisos a los roles a la vez.
Cómo se unen los usuarios, los grupos, las funciones y los permisos
En un sistema RBAC robusto, los usuarios pueden agregarse a un rol individualmente para crear la colección de usuarios en el rol o los grupos se pueden agregar a un rol para agregar una colección de usuarios al rol a la vez. De cualquier manera, el rol obtiene su colección de usuarios al ser agregados individualmente o agregando grupos al rol o agregando una combinación de usuarios y grupos al rol. Los permisos se pueden considerar de la misma manera.
Los permisos se pueden agregar a los roles individualmente para crear la colección de permisos dentro del rol o se pueden agregar conjuntos de permisos a un rol. Por último, se puede agregar una combinación de permisos y conjuntos de permisos a un rol. De cualquier manera, el rol obtiene su colección de permisos al agregarse individualmente o al agregar conjuntos de permisos a un rol.
Todo el propósito de los roles es casar a los usuarios con los permisos. Por tanto, un Rol es la UNIÓN de Usuarios y Permisos.
¿Qué son las reclamaciones?
Claim = Qué “es” un sujeto
Las reclamaciones NO son permisos. Como se señaló en respuestas anteriores, un reclamo es lo que un sujeto “es” no lo que un sujeto “puede hacer”.
Las reclamaciones no reemplazan las funciones ni los permisos, son piezas adicionales de información que se pueden utilizar para tomar una decisión de autorización.
Cuándo usar reclamos
He encontrado que las Reclamaciones son útiles cuando se necesita tomar una decisión de Autorización cuando el Usuario no puede ser agregado a un Rol o la decisión no se basa en la asociación de Usuario con Permiso. El ejemplo de un usuario de Facebook causa esto. Un usuario de Facebook puede no ser alguien que se agregue a un “rol” … es solo un visitante autenticado a través de Facebook. Aunque no encaja perfectamente en RBAC, es un dato sobre el que tomar una decisión de autorización.
@CodingSoft usó la metáfora del club nocturno en una respuesta anterior, que me gustaría extender. En esa respuesta, la Licencia de conducir se usó como un ejemplo que contenía un conjunto de Reclamaciones donde la Fecha de nacimiento representa una de las Reclamaciones y el valor de la Reclamación por fecha de nacimiento se usa para probar la regla de autorización. El gobierno que emitió la licencia de conducir es la autoridad que otorga autenticidad al reclamo. Por lo tanto, en un escenario de club nocturno, el portero en la puerta mira la licencia de conducir de la persona, se asegura de que fue emitida por una autoridad confiable al examinar si es o no una identificación falsa (es decir, debe ser una identificación válida emitida por el gobierno), luego mira la fecha de nacimiento (uno de los muchos reclamos en una licencia de conducir), luego usa ese valor para determinar si la persona tiene la edad suficiente para ingresar al club. Si es así, la persona aprueba la regla de autorización en virtud de tener un Reclamo válido, no por estar en algún Rol.
Ahora, con esa base en mente, me gustaría extender eso más. Supongamos que el edificio donde se encuentra el club nocturno contiene oficinas, habitaciones, una cocina, otros pisos, ascensores, un sótano, etc. donde solo pueden ingresar los empleados del club. Además, ciertos empleados pueden tener acceso a ciertos lugares que otros empleados pueden no tener. Por ejemplo, un Gerente puede tener acceso a un piso de oficina arriba al que otros empleados no pueden acceder. En este caso hay dos roles. Gerente y Empleado.
Si bien el acceso de los visitantes al área pública del club nocturno está autorizado por un solo reclamo, como se explicó anteriormente, los empleados necesitan acceso por rol a otras salas no públicas restringidas. Para ellos, una licencia de conducir no es suficiente. Lo que necesitan es una credencial de empleado que escanean para ingresar a las puertas. En algún lugar hay un sistema RBAC que otorga credenciales en el rol de administrador para acceder al piso superior y credenciales en el rol de empleado para acceder a otras salas.
Si por alguna razón es necesario agregar / eliminar ciertas salas por función, esto se puede hacer usando RBAC, pero no es una buena opción para un reclamo.
Permisos en software
Codificar roles en la aplicación es una mala idea. Esto codifica el propósito del rol en la aplicación. Lo que la aplicación debería tener son solo permisos que actúen como banderas de funciones. Donde las banderas de características se hacen accesibles por configuración, los permisos se hacen accesibles por el contexto de seguridad del usuario que se deriva de la colección DISTINCT de permisos recopilados de todos los roles en los que se ha colocado el usuario. Esto es lo que yo llamo los “permisos efectivos”. La aplicación solo debe presentar un menú de posibles permisos para funciones / acciones. El sistema RBAC debería hacer el trabajo de casar esos Permisos con Usuarios a través de Roles. De esta manera, no hay una codificación rígida de los roles y la única vez que cambia un permiso es cuando se elimina o se agrega uno nuevo. Una vez que se agrega un permiso al software, nunca debe cambiarse. Solo debe eliminarse cuando sea necesario (es decir, cuando una función se suspende en una nueva versión) y solo se pueden agregar nuevas.
Una nota final.
Conceder vs Denegar
Un sistema RBAC robusto e incluso un sistema CBAC deberían distinguir entre subvenciones y denegaciones.
La adición de un permiso a un rol debe incluir una SUBVENCIÓN o una DENEGACIÓN. Cuando se marcan los Permisos, todos los Permisos CONCEDIDOS deben agregarse a la lista de Usuarios de Permisos Efectivos. Luego, después de todo lo que está hecho, una lista de Permisos DENEGADOS debería hacer que el sistema elimine esos Permisos de la lista de Permisos Efectivos.
Esto permite a los administradores “modificar” los permisos finales de un tema. Es mejor si los permisos también se pueden agregar a los usuarios directamente. De esta manera, puede agregar un usuario a un rol de administrador y obtendrán acceso a todo, pero quizás quieras NEGAR el acceso al baño de mujeres porque el usuario es un hombre. Por lo tanto, agrega el usuario masculino al rol de administrador y agrega un permiso al objeto Usuario con DENY para que solo le quite el acceso a la habitación de esa dama.
En realidad, este sería un buen candidato para una Reclamación. Si el usuario tiene un reclamo “género = masculino”, entonces estar en el rol de administrador le da acceso a todas las habitaciones, pero el baño de mujeres también requiere el reclamo género = femenino y el baño de hombres requiere reclamo género = masculino. De esta manera, uno no tendría que configurar un permiso DENY a los Usuarios masculinos ya que la aplicación de la Reclamación se encarga de eso para todos con una sola regla de autorización. Sin embargo, se puede hacer de cualquier manera.
El caso es que con DENIAL of Permissions se facilita la gestión de los Roles porque se pueden implementar excepciones.
A continuación se muestra un diagrama que hice hace mucho tiempo que muestra el modelo RBAC. No tengo un gráfico para las Reclamaciones, pero puedes imaginar que son solo atributos adjuntos a los Usuarios donde sea que estén. Además, el diagrama no muestra Grupos (necesito actualizarlo en algún momento).
Espero que esto ayude.
Este es un diagrama del RBAC descrito arriba
Actualización el 7 de abril de 2019
Basado en los comentarios de @Brent (gracias) … eliminó las referencias innecesarias a respuestas anteriores y explicó la base original de la metáfora del “club nocturno” proporcionada por @CodingSoft para hacer que esta respuesta sea comprensible sin tener que leer otras respuestas.
No estoy completamente de acuerdo con la respuesta de Emran.
[Authorize(Roles="Sale")]
Es ingenuo
La pregunta es como
[Authorize(Roles="CustomerCreator")]
es diferente de
[ClaimAuthorize(Permission="CanCreateCustomer")]
Si ambos son igualmente buenos, ¿por qué necesitamos reclamarlo?
Creo que porque
El concepto de reclamaciones es más genérico en comparación con el rol.
En el contexto del ejemplo anterior, podemos decir que “CustomerCreator” es un reclamo de tipo “role” proporcionado por “Asp.NETroleProvider”
Ejemplos adicionales de reclamaciones.
-
“AAA” es un reclamo de tipo “MYExamSite.Score” proporcionado por “MYExamSite.com”
-
“Gold” es un reclamo del tipo “MYGYM.Membershiptype” proporcionado por “MYGYMApp”