remarks example cref c# asp.net-mvc authorization

example - remarks c#



Autorizar el atributo con mĂșltiples funciones (5)

Asegúrese de derivar su clase de atributo personalizado de System.Web.Mvc.AuthorizeAttribute y NO System.Web.Http.AuthorizeAttribute .

Tuve el mismo problema. Una vez que lo cambié, todo funcionó.

Es posible que también desee agregar lo siguiente a su clase de atributo personalizado:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]

Me gustaría agregar Autorización a un controlador para múltiples Roles a la vez.

Normalmente eso se vería así:

[Authorize(Roles = "RoleA,RoleB,RoleC")] public async Task<ActionResult> Index() { }

Pero he almacenado mis roles en constelaciones, ya que podrían cambiar o ampliarse en algún momento.

public const RoleA = "RoleA"; public const RoleB = "RoleB"; public const RoleC = "RoleC";

No puedo hacer esto, ya que la cadena debe conocerse en tiempo de compilación:

[Authorize(Roles = string.join(",",RoleA,RoleB,RoleC)] public async Task<ActionResult> Index() { }

¿Hay alguna forma de eludir el problema?

PODRÍA escribir un const que simplemente contenga "RoleA, RoleB, RoleC" - pero no me gustan las cadenas mágicas y esta es una cadena mágica. Cambiar el nombre de una Función y olvidarse de cambiar la cadena combinada sería un desastre.

Estoy usando MVC5. La identidad de ASP.NET y el rol son conocidos en tiempo de compilación.


Intente crear un atributo de autorización personalizado como this .

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

Suponiendo que sus roles serán los mismos para múltiples controladores, cree una clase auxiliar:

public static class Role { public const string Administrator = "Administrator"; public const string Assistant = "Assistant"; }

Entonces úsalo así:

public class MyController : Controller { [AuthorizeRoles(Role.Administrator, Role.Assistant)] public ActionResult AdminOrAssistant() { return View(); } }


Lo que hice fue la respuesta en @Tieson

Me pellizco un poco en su respuesta. En lugar de cadena. ¿Por qué no convertirlo a la lista?

Aquí está mi respuesta:

public class AuthorizeRolesAttribute : AuthorizeAttribute { private new List<string> Roles; public AuthorizeRolesAttribute(params string[] roles) : base() { Roles = roles.toList() } }

Y luego verifique si el rol es válido anulando OnAuthorization

public override void OnAuthorization(HttpActionContext actionContext) { if (Roles == null) HandleUnauthorizedRequest(actionContext); else { ClaimsIdentity claimsIdentity = HttpContext.Current.User.Identity as ClaimsIdentity; string _role = claimsIdentity.FindFirst(ClaimTypes.Role).Value; bool isAuthorize = Roles.Any(role => role == _role); if(!isAuthorize) HandleUnauthorizedRequest(actionContext); } }

Y ahí lo tienes, ahora está validando si el rol está autorizado para acceder al recurso


No sé por qué todos aceptaron esa respuesta. Hice exactamente como lo mencioné y ahora no hay ningún control de autorización. Los usuarios anónimos ahora pueden conectarse a todos los métodos decorados con este atributo personalizado ... La mejor y más sencilla forma que encontré para resolver este problema es simplemente concatenar roles en el atributo Autorizar.

[Authorize(Roles = CustomRoles.Admin + "," + CustomRoles.OtherRole)]

con CustomRole una clase con cadenas constantes como esta:

public static class CustomRoles { public const string Admin = "Admin"; // and so on.. }


Siento que un atributo de autorización personalizado es excesivo para este problema a menos que tenga una gran cantidad de funciones.

Como la cadena debe conocerse en tiempo de compilación, ¿por qué no crear una clase Role estática que contenga cadenas públicas de los roles que ha definido y luego agregar cadenas separadas por comas con determinados roles que quiera autorizar?

public static class Roles { public const string ADMIN = "Admin"; public const string VIEWER = "Viewer"; public const string ADMIN_OR_VIEWER = ADMIN + "," + VIEWER; }

Y luego puede usar el atributo Authorize Attribute como así en la clase de controlador o el método de controlador (o ambos):

[Authorize(Roles = Roles.ADMIN] public class ExampleController : Controller { [Authorize(Roles = Roles.ADMIN_OR_VIEWER) public ActionResult Create() { ..code here... } }