2009-08-22 22 views
10

Supongamos que un desarrollador de alta velocidad tiene la tarea de crear una aplicación bancaria a la que accedan muchas personas diferentes. Cada persona desearía acceder a su propia información de cuenta, pero no querría que otras personas accedieran a ella. Me gustaría saber cuál es la mejor práctica para restringir el acceso en una aplicación MVC para que solo el usuario que posee la información (o un administrador) pueda acceder a ella.¿Cuál es el mejor mecanismo para implementar seguridad granular (es decir, autorización) en una aplicación ASP.NET MVC?

El atributo Authorize nos permite restringir por función. Si bien este es un punto de partida, parece que cualquier usuario autenticado podría obtener acceso a la información de cualquier otro usuario.

ActionFilters parecen ofrecer la opción de un control un poco más granular y probablemente podrían utilizarse para realizar la tarea. Sin embargo, no estoy seguro de si serían el enfoque recomendado.

Cualquier orientación o idea es bienvenida.

+9

¿Qué es un "desarrollador de alta velocidad"? –

Respuesta

0

Creo que lo tiene bien, el enfoque de ActionFilter es acertado.

Creé un conjunto de filtros de acción personalizados que heredó de AuthorizeAttribute.

Además de la funcionalidad del atributo Autorizar, puede implementar una política de propietario más estricto de forma limpia.

HTH,

Dan

+1

Gracias Dan! ¿Cuáles son sus sugerencias para implementar una "política de propietario más estricta"? ¿Es esto algo similar a lo que Marcos ha descrito arriba? –

+0

Exactamente Anthony, el último párrafo en particular de la respuesta de Marcos. Me gustaría derivar sus filtros personalizados del filtro Autorizar, ya que necesitará un IPrincipal autorizado para verificar en contra de la ACL. –

9

ActionFilter es probablemente un buen punto de partida, pero dependiendo de su arquitectura, es posible que desee considerar si la defensa del perímetro es lo suficientemente bueno.

Si básicamente está construyendo una aplicación ASP.NET MVC de capa única (y puede haber razones perfectamente razonables para hacerlo), un ActionFilter proporcionará una defensa que sea lo suficientemente buena y al mismo tiempo sea muy simple de aplicar .

Por otro lado, si su aplicación es una aplicación de varias capas, Defensa en profundidad es más apropiada. En ese caso, debería considerar aplicar la lógica de autorización en el Modelo de dominio, o incluso en la capa de Acceso a datos. Esto asegurará que si alguna vez desarrolla otra aplicación basada en el mismo Modelo de Dominio (por ejemplo, un servicio web), la lógica de autorización aún se aplicaría.

No importa lo que haga, le recomiendo encarecidamente que base la implementación de la autorización real en IPrincipal.

En una nota más específica, lo que está preguntando aquí se modela mejor con la autorización basada en ACL: Establezca una ACL en cada perfil de usuario que de forma predeterminada otorga acceso solo al usuario y al administrador. Si/cuando más adelante necesita expandir la aplicación para permitir el acceso delegado a los perfiles de otros usuarios (no sé si eso es remotamente realista en su caso específico), puede hacerlo agregando una nueva entrada a la ACL.

En tal caso, evaluar el acceso implica recuperar la ACL para el recurso solicitado y verificar si el usuario actual (IPrincipal) está incluido en esa ACL. Tal operación es muy probable que involucre operaciones fuera del proceso (buscando la ACL en una base de datos), por lo que tenerla como una parte implícita de una aplicación escondiéndola detrás de un ActionFilter parece que podría ocultar algunos problemas de rendimiento. En tal caso, consideraría hacer que el modelo de autorización sea un poco más explicto/visible.

+1

¡Mark, esta es una excelente estrategia! ¡Gracias! En la mayoría de mis proyectos anteriores, escribimos nuestros propios componentes de seguridad para administrar perms, usuarios, grupos, roles, etc. y eludimos la arquitectura de membresía de ASP.NET específicamente para acomodar el control de acceso a niveles más bajos. Tenía la ESPERANZA de que había una forma más fácil de implementar permisos en MVC que hacerla mía. Desde mi publicación inicial, terminé escribiéndolo de todos modos, pero adopté un enfoque híbrido. Utilicé la membresía y los proveedores de roles de ASP.NET para permisos básicos y rol mgmt, pero desarrollé mi propio grupo y gestión de permisos para un mejor control granular. –

+0

Cuando un usuario intenta realizar una acción (en un controlador), verifico sus roles para asegurarme de que tiene acceso "básico". Si no, lo redirijo. Si él tiene acceso básico, invoco una función más granular para verificar sus permisos reales contra el tipo de objeto específico y/o la instancia a la que está intentando acceder. En este momento, todavía no lo he implementado como un filtro de acción, pero estoy llamando esto dentro de cada acción. Voy a refactorizarlo en breve. –

+0

Me alegro de que pueda usar la respuesta; también puede consultar esta respuesta que está relacionada de alguna manera: http://stackoverflow.com/questions/1335315/access-control-in-asp-net-mvc-depending-on -input-parameters-service-layer/1336404 # 1336404 –

1

Según mi punto de vista, si tiene una aplicación de capa única, entonces la autorización es la mejor opción y también actionfilter es mucho mejor y más simple de usar. Pero si su aplicación es multicapa, entonces usted usa la lista de control de acceso [ACL].

0

Si alguna vez quiere externalizar la autorización, puede echar un vistazo a las implementaciones basadas en XACML.

Cuestiones relacionadas