¿Deben realizarse verificaciones de permisos de usuario en el modelo o el controlador? ¿Y quién debe encargarse de las verificaciones de permisos, el objeto Usuario o algún ayudante de UserManagement?
¿Dónde debería pasar?
Comprobación en el controlador:
class MyController {
void performSomeAction() {
if (user.hasRightPermissions()) {
model.someAction();
}
}
...
Tener las comprobaciones en el controlador ayuda a que los modelos sean acciones simples, para que podamos mantener toda la lógica en los controladores.
Comprobación en el modelo:
class MyModel {
void someAction() {
if (user.hasRightPermissions()) {
...
}
}
...
Al poner los controles en el Modelo, complicamos el Modelo, pero también nos aseguramos de no permitir accidentalmente que los usuarios hagan cosas que no deben hacer en el Controlador.
¿Y por quien?
Una vez que nos instalamos en el lugar, ¿quién debería hacer los controles? ¿El usuario?
Class User {
bool hasPermissions(int permissionMask) {
...
}
...
Pero en realidad no es responsabilidad del usuario saber a qué puede acceder, así que ¿quizás alguna clase de ayuda?
Class UserManagement {
bool hasPermissions(User user, int permissionMask) {
...
}
...
Sé que es común hacer una sola pregunta, bueno, una pregunta, pero creo que se pueden responder muy bien juntos.
fuente
La seguridad es una preocupación transversal, por lo tanto, debe implementarse en varias capas. Lo que sigue es un ejemplo para MVC, pero el concepto se aplica a otras arquitecturas y / o patrones, solo tiene que identificar los puntos de aplicación.
¿Dónde debería pasar?
Las vistas pueden contener elementos de la interfaz de usuario (widgets, botones, menús, etc.) que deben mostrarse o no para algunos usuarios, según sus permisos. Esto podría ser una responsabilidad del motor de visualización , ya que no desea que cada vista maneje esto por sí solo. Dependiendo del tipo de elementos que esté autorizando, mueva esta responsabilidad a otro lugar. Por ejemplo, piense en un menú en el que algunos elementos deben mostrarse y otros no. Los elementos se pueden implementar como una lista en algún lugar y filtrar esa lista según los permisos y luego reenviarla a la vista.
Los controladores responden a las solicitudes, por lo que si un usuario no tiene permiso para ejecutar una acción, se debe verificar antes de invocar la acción, transfiriendo la responsabilidad al invocador de la acción en lugar de mantenerla en el controlador. Esto tiene la ventaja de mantener limpio su controlador y, si algo cambia en los permisos, no tiene que examinar los controladores para aplicar esos cambios.
Los recursos se muestran según los permisos. Esto normalmente se realiza a nivel de base de datos , ya que no desea extraer todo de la base de datos y luego aplicar permisos.
Como puede ver, dependiendo de lo que quiera autorizar, hay diferentes lugares donde esto debería hacerse. El objetivo es ser lo más discreto posible, de modo que, cuando cambie su política de seguridad, pueda aplicarla fácilmente, preferiblemente sin alterar el código de su aplicación. Esto podría no ser válido para aplicaciones pequeñas, donde el conjunto de permisos es bastante pequeño y no cambia muy a menudo. Sin embargo, en aplicaciones empresariales, la historia es bastante diferente.
¿Quién debería hacerlo?
Claramente no es el modelo. Cada capa debe tener un punto de cumplimiento que maneje la autorización. El texto en cursiva anterior resalta el posible punto de aplicación para cada nivel.
Echa un vistazo a XACML . No tiene que implementarlo tal como está, pero le dará algunas instrucciones que puede seguir.
fuente
Yo uso el siguiente esquema. Vale la pena decir que la mayoría de las comprobaciones de permisos de usuario se pueden dividir en dos casos generales:
El acceso a la acción del controlador sin verificar los atributos generalmente se implementa en marcos MVC. Esto es simple en absoluto: usted define reglas, sus usuarios tienen un rol. Simplemente verifica que el usuario tenga permiso para buscar su papel en las reglas.
El acceso del usuario a un modelo particular debe definirse en el modelo. (El actor es la clase de usuario base. Suponga que puede ser cliente, vendedor o invitado).
Colocar esa lógica en el modelo trae algunas ganancias. El método de verificación de acceso se puede heredar, no necesita crear clases adicionales, puede usar las ventajas generales de OOP.
Luego, para simplificar la verificación de acceso, tomamos algunas suposiciones que casi siempre se implementan por simplicidad y buen estilo:
Con estos supuestos, las acciones que usan la identificación del modelo pueden asociarse con una instancia de modelo particular. De hecho, la mayoría de las acciones se pueden transformar y mover fácilmente para ajustarse a los supuestos establecidos anteriormente.
Luego, se debe definir y heredar alguna clase de controlador abstracto base.
Puede llamar al método SomeController :: checkModelAccess ($ id) cuando construya sus menús y decida si desea mostrar algún enlace.
fuente
Tanto en modelo como en vista
En la vista , porque la interfaz de usuario no debe mostrar los elementos de la interfaz de usuario que están restringidos al usuario actual
(como, digamos, el botón "Eliminar" debe mostrarse a las personas con los permisos adecuados)
En el modelo , porque su aplicación probablemente tenga algún tipo de API, ¿verdad? La API también tiene que verificar los permisos y probablemente reutiliza el Modelo.
(por ejemplo, tiene el botón "Eliminar" en la interfaz de usuario y el método de API "http: / server / API / DeleteEntry / 123" al mismo tiempo
fuente
MVC es un patrón de presentación. Como tal, la vista y el controlador solo deben tener responsabilidades con respecto a la presentación. Algunos permisos se aplican a la presentación, como un modo experto, características experimentales de IU o diseños diferentes. Esos pueden ser manejados por el controlador MVC.
Muchos otros tipos de permisos son relevantes en varias capas de la aplicación. Por ejemplo, si desea tener usuarios que solo puedan ver datos y no cambiar las cosas:
Hay alguna duplicación en este enfoque. Pero como la presentación es usualmente volátil, uno puede hacer un buen caso para verificar el permiso en la parte generalmente más estable de la aplicación, incluso si eso significa algunas verificaciones redundantes en caso de que la capa de presentación funcione según lo previsto.
fuente