permisos - ASP.NET MVC3 Role and Permission Management-> Con Runtime Permission Assignment
roles asp net c# (4)
ASP.NET MVC les permite a los usuarios la capacidad de asignar permisos a la funcionalidad (es decir, acciones) en el momento del diseño .
[Authorize(Roles = "Administrator,ContentEditor")]
public ActionResult Foo()
{
return View();
}
Para comprobar realmente el permiso, uno puede usar la siguiente declaración en una vista (Razor):
@if (User.IsInRole("ContentEditor"))
{
<div>This will be visible only to users in the ContentEditor role.</div>
}
El problema con este enfoque es que todos los permisos deben configurarse y asignarse como atributos en el momento del diseño . (Los atributos se compilan con el DLL, por lo que actualmente no conozco ningún mecanismo para aplicar atributos (para permitir permisos adicionales) como [Autorizar (Roles = "Administrador, Editor de contenido")] en tiempo de ejecución .
En nuestro caso de uso, el cliente debe poder cambiar qué usuarios tienen qué permisos después de la implementación .
Por ejemplo, el cliente puede desear permitir que un usuario en la función ContentEditor
edite algún contenido de un tipo particular. Tal vez a un usuario no se le permitió editar los valores de la tabla de búsqueda, pero ahora el cliente quiere permitir esto sin otorgar al usuario todos los permisos en el siguiente rol superior. En cambio, el cliente simplemente quiere modificar los permisos disponibles para el rol actual del usuario.
¿Qué opciones hay disponibles para permitir que los permisos en Controladores MVC / Vistas / Acciones se definan fuera de los atributos (como en una base de datos) y se evalúen y apliquen en el tiempo de ejecución?
De ser posible, nos gustaría mantenernos lo más cerca posible de la funcionalidad de membresía y función de proveedor de roles de ASP.NET para que podamos continuar aprovechando los demás beneficios que brinda.
Gracias de antemano por cualquier idea o idea.
¿Qué opciones hay disponibles para permitir que los permisos en Controladores MVC / Vistas / Acciones se definan fuera de los atributos (como en una base de datos) y se evalúen y apliquen en el tiempo de ejecución?
Un atributo Autorizar personalizado es una posibilidad para lograr esto:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
Roles = ... go ahead and fetch those roles dynamically from wherever they are stored
return base.AuthorizeCore(httpContext);
}
}
y entonces:
[MyAuthorize]
public ActionResult Foo()
{
return View();
}
Como soy perezoso, no me molestaría rodar mi propio atributo y usé FluentSecurity para esto. Además de la capacidad de aplicar reglas en tiempo de ejecución, permite una forma personalizada de verificar la membresía de roles. En mi caso, tengo una configuración de archivo de configuración para cada función, y luego implemento algo como lo siguiente;
// Map application roles to configuration settings
private static readonly Dictionary<ApplicationRole, string>
RoleToConfigurationMapper = new Dictionary<ApplicationRole, string>
{
{ ApplicationRole.ExceptionLogViewer, "ExceptionLogViewerGroups" }
};
los roles de la aplicación se aplican como tal
SecurityConfigurator.Configure(
configuration =>
{
configuration.GetAuthenticationStatusFrom(() =>
HttpContext.Current.User.Identity.IsAuthenticated);
configuration.GetRolesFrom(() =>
GetApplicationRolesForPrincipal(HttpContext.Current.User));
configuration.ForAllControllers().DenyAnonymousAccess();
configuration.For<Areas.Administration.Controllers.LogViewerController>()
.RequireRole(ApplicationRole.ExceptionLogViewer);
});
filters.Add(new HandleSecurityAttribute());
y luego el control se realiza por
public static object[] GetApplicationRolesForPrincipal(IPrincipal principal)
{
if (principal == null)
{
return new object[0];
}
List<object> roles = new List<object>();
foreach (KeyValuePair<ApplicationRole, string> configurationMap in
RoleToConfigurationMapper)
{
string mappedRoles = (string)Properties.Settings.Default[configurationMap.Value];
if (string.IsNullOrEmpty(mappedRoles))
{
continue;
}
string[] individualRoles = mappedRoles.Split('','');
foreach (string indvidualRole in individualRoles)
{
if (!roles.Contains(configurationMap.Key) && principal.IsInRole(indvidualRole))
{
roles.Add(configurationMap.Key);
if (!roles.Contains(ApplicationRole.AnyAdministrationFunction))
{
roles.Add(ApplicationRole.AnyAdministrationFunction);
}
}
}
}
return roles.ToArray();
}
Por supuesto, puede obtener roles de una base de datos. Lo bueno de esto es que puedo aplicar diferentes reglas durante el desarrollo, ¡además de que alguien ya ha hecho el trabajo duro por mí!
Si necesita hacer una autorización basada en Método o Controlador (denegar el acceso a todo el método o controlador), puede anular la Autorización previa en la base del controlador y realizar su autorización. A continuación, puede compilar una tabla para buscar qué permisos se asignan a ese controlador / método e ir desde allí.
También puede hacer un filtro global personalizado, que es muy similar.
Otra opción, usando su segundo enfoque, es decir algo como esto:
@if (User.IsInRole(Model.MethodRoles))
{
<div>This will be visible only to users in the ContentEditor role.</div>
}
Y luego en su controlador llene MethodRoles con los roles asignados a ese método.
También podría considerar realizar tareas basadas en la seguridad y asignar dinámicamente permisos para realizar esas tareas a diferentes grupos.
Tendría que manipular un poco al proveedor para trabajar con esto, pero es posible mantenerse en línea con la autorización .net
http://www.lhotka.net/weblog/PermissionbasedAuthorizationVsRolebasedAuthorization.aspx