none
Aplicacion MVC Intranet con Autenticación Windows y Autorización. RRS feed

  • Pregunta

  • Hola,

    Llevo tiempo estudiando el sistems de autenticación en una aplicación ASP.NET MVC 3 Razor y en varios posts se comenta que es bueno intentar usar las clases integradas en lugar de una usar una clásica tabla de Usuarios.

    El sistema de Autenticación de Windows me parece adecuado salvo que no he encontrado dónde puedo limitar el acceso de un usuario del dominio a una o ciertas partes de la aplicación de una manera dinámica y no con el

    [Authorize(Users = @"CONTOSO\Rick, CONTOSO\Keith, CONTOSO\Mike")]

    dónde los usuarios tienen que estar en el código. Los roles creo que no me servirían porque no tengo control de los usuarios de dominio, sólo conozco el login.

    Cuál sería la manera más simple de Autotizar sólo a ciertos usuarios (dados de alta en una tabla) a acceder a una aplicación y por el contrario a los que no les esá permitido que redireccionen a una ventana de mensaje de error.

    Mi opción ha sido realizar una funcion de ValidateUser(string slogin) y llamarla desde la primera ventana (Home/Index.cshtml) con el @Context.User.Identity.Name.

    Aparte de ser una opción que no me encanta, supongo que, si no lo controlo, podría tener problemas de acceso cuando se accede directamente a una ruta del tipo Aplicacion/Categorias/Edit/3 sin que el flujo pasase por la Index.cshtml. Podría forzar que se pasase o deberia replantear el [Autorize] de alguna manera. Se podría pasar de algun modo los nombres que me extraiga una funcion a los Users del [Autorize]?

    Muchas gracias, hacéis un gran trabajo de soporte.

    Saludos,

    Oriol Civit

    lunes, 18 de marzo de 2013 9:19

Todas las respuestas

  • Buenas!

    1. No debes meter código de autorización en una vista (Index.cshtml) porque como dices luego tendrás problemas si alguien navega a cualquier otro sitio. Aunque meterlo en _ViewStart.cshtml te funcionaría estarías rompiendo el patrón MVC que dice que las vistas tan solo deben mostrar información así que mejor olvídemonos de ellas para realizar tareas de autorización :)

    2. Si no lo puedes meter en las vistas, la otra opción lógica son los controladores. En lugar de meter el código en Index.html lo metes en la acción del controlador que termina devolviendo esta vista. Claro que esto tiene el mismo problema que antes, en el sentido de que si alguien no navega a /home/index (o la acción que sea que tiene este código) no te funcionaria.

    Puedes "copiar y pegar" esta llamada a ValidateUser y ponerla en toooodas las acciones que requieran esta validación, pero esto aparte de un coñazo es muy proclive a errores. Para ello se idearon los filtros en ASP.NET MVC. Con ellos decoras una acción con un filtro y se ejecuta este filtro, usualmente antes de ejecutar la acción. [Authorize] es un ejemplo de un filtro. Sigues teniendo que decorar tooooodas las acciones, eso sí. Usar filtros tiene más ventajas: si aplicas el filtro al controlador (en lugar de a una acción) se aplicará a todas las acciones de dicho controlador. Y si lo registras como filtro global se aplicará a todas las acciones de todos los controladores.

    Una posible solución a tu problema, pasa por crear un filtro que realice dicha llamda a ValidateUser. En tu caso se trata de un filtro de autorización, ya que su función es esa: autorizar o no una llamada. Luego tu decides a que acciones aplicas este filtro.

    Y cuan complejo es crear un filtro de autorización? Pues no mucho, básicamente te basta con derivar de FilterAttribute e implementar IAuthorizationFilter. Esto te obliga a implementar un solo método (OnAuthorization creo que se llama). Dicho método debe "no hacer nada" si la llamada se autoriza o colocar un ActionResult específico (un RedirectResult o lo que sea) que se ejecutará "en lugar" de la acción si esta no se autoriza. Aquí lo explican con más detalle: http://geekswithblogs.net/brians/archive/2010/07/08/implementing-a-custom-asp.net-mvc-authorization-filter.aspx

    [Authorize] es un filtro de autorización por lo que realmente lo que estás haciendo es implementarte tu propio "Authorize".

    Hay más opciones, pero creo que esta sería la mejor te puede encajar!

    Saludos!


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis

    lunes, 18 de marzo de 2013 22:01