tutorial net mvc example entre diferencias crear autenticacion asp asp.net-mvc controller roles

asp.net-mvc - net - web forms c#



Permitir múltiples roles para acceder a la acción del controlador (8)

Mejor código con la adición de una subclase AuthorizeRole.cs

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] class AuthorizeRoleAttribute : AuthorizeAttribute { public AuthorizeRoleAttribute(params Rolenames[] roles) { this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r))); } protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAuthenticated) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action", "Unauthorized" }, { "controller", "Home" }, { "area", "" } } ); //base.HandleUnauthorizedRequest(filterContext); } else { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action", "Login" }, { "controller", "Account" }, { "area", "" }, { "returnUrl", HttpContext.Current.Request.Url } } ); } } }

Como usar esto

[AuthorizeRole(Rolenames.Admin,Rolenames.Member)] public ActionResult Index() { return View(); }

Ahora mismo decoro un método como este para permitir que los "miembros" accedan a mi acción del controlador

[Authorize(Roles="members")]

¿Cómo permito más de un rol? Por ejemplo, lo siguiente no funciona pero muestra lo que estoy tratando de hacer (permitir el acceso de "miembros" y "administrador"):

[Authorize(Roles="members", "admin")]


Otra opción es usar un único filtro de autorización como lo publicó, pero elimine las citas internas.

[Authorize(Roles="members, admin")]


Otra solución clara, puede usar constantes para mantener la convención y agregar múltiples atributos [Autorizar]. Mira esto:

public static class RolesConvention { public const string Administrator = "Administrator"; public const string Guest = "Guest"; }

Luego en el controlador:

[Authorize(Roles = RolesConvention.Administrator )] [Authorize(Roles = RolesConvention.Guest)] [Produces("application/json")] [Route("api/[controller]")] public class MyController : Controller


Para MVC4, usando un Enum ( UserRoles ) con mis roles, uso un AuthorizeAttribute personalizado.

En mi acción controlada, hago:

[CustomAuthorize(UserRoles.Admin, UserRoles.User)] public ActionResult ChangePassword() { return View(); }

Y uso un AuthorizeAttribute personalizado como ese:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class CustomAuthorize : AuthorizeAttribute { private string[] UserProfilesRequired { get; set; } public CustomAuthorize(params object[] userProfilesRequired) { if (userProfilesRequired.Any(p => p.GetType().BaseType != typeof(Enum))) throw new ArgumentException("userProfilesRequired"); this.UserProfilesRequired = userProfilesRequired.Select(p => Enum.GetName(p.GetType(), p)).ToArray(); } public override void OnAuthorization(AuthorizationContext context) { bool authorized = false; foreach (var role in this.UserProfilesRequired) if (HttpContext.Current.User.IsInRole(role)) { authorized = true; break; } if (!authorized) { var url = new UrlHelper(context.RequestContext); var logonUrl = url.Action("Http", "Error", new { Id = 401, Area = "" }); context.Result = new RedirectResult(logonUrl); return; } } }

Esto es parte del FNHMVC modificado por Fabricio Martínez Tamayo https://github.com/fabriciomrtnz/FNHMVC/


Si quieres usar roles personalizados, puedes hacer esto:

Clase de CustomRoles :

public static class CustomRoles { public const string Administrator = "Administrador"; public const string User = "Usuario"; }

Uso

[Authorize(Roles = CustomRoles.Administrator +","+ CustomRoles.User)]

Si tiene pocos roles, tal vez pueda combinarlos (para mayor claridad) de esta manera:

public static class CustomRoles { public const string Administrator = "Administrador"; public const string User = "Usuario"; public const string AdministratorOrUser = Administrator + "," + User; }

Uso

[Authorize(Roles = CustomRoles.AdministratorOrUser)]


Si te encuentras aplicando esos 2 roles a menudo, puedes envolverlos en su propio Autorizar. Esta es realmente una extensión de la respuesta aceptada.

using System.Web.Mvc; public class AuthorizeAdminOrMember : AuthorizeAttribute { public AuthorizeAdminOrMember() { Roles = "members, admin"; } }

Y luego aplica tu nueva autorización a la Acción. Creo que esto se ve más limpio y se lee fácilmente.

public class MyController : Controller { [AuthorizeAdminOrMember] public ActionResult MyAction() { return null; } }


Una posible simplificación sería la subclase AuthorizeAttribute :

public class RolesAttribute : AuthorizeAttribute { public RolesAttribute(params string[] roles) { Roles = String.Join(",", roles); } }

Uso:

[Roles("members", "admin")]

Semánticamente es la misma que la respuesta de Jim Schmehil.


Usando AspNetCore 2.x, tienes que ir de una manera un poco diferente:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class AuthorizeRoleAttribute : AuthorizeAttribute { public AuthorizeRoleAttribute(params YourEnum[] roles) { Policy = string.Join(",", roles.Select(r => r.GetDescription())); } }

solo úsalo así:

[Authorize(YourEnum.Role1, YourEnum.Role2)]