¿Cómo implementar un atributo Autorizar personalizado para el siguiente caso?

entonces tengo mi método de acción

[Authorize(Roles="Admin")] public ActionResult EditPosts(int id) { return View(); } 

En mi caso, necesito autorizar a los administradores para que puedan editar las publicaciones, pero (aquí viene la parte buena), también necesito permitir que el creador de la publicación pueda editar la publicación que es un usuario normal. Entonces, ¿cómo puedo filtrar al usuario que creó la publicación, así como a los administradores, pero dejar a los demás no autorizados? Estoy recibiendo la identificación PostEntry como un parámetro de ruta, pero eso es después del atributo y también los atributos solo aceptan parámetros constantes, parece algo muy difícil, sus respuestas son muy apreciadas, ¡Salud!

Puede escribir un atributo de autorización personalizado:

 public class AuthorizeAdminOrOwnerOfPostAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var authorized = base.AuthorizeCore(httpContext); if (!authorized) { // The user is not authenticated return false; } var user = httpContext.User; if (user.IsInRole("Admin")) { // Administrator => let him in return true; } var rd = httpContext.Request.RequestContext.RouteData; var id = rd.Values["id"] as string; if (string.IsNullOrEmpty(id)) { // No id was specified => we do not allow access return false; } return IsOwnerOfPost(user.Identity.Name, id); } private bool IsOwnerOfPost(string username, string postId) { // TODO: you know what to do here throw new NotImplementedException(); } } 

y luego decora tu acción de controlador con ella:

 [AuthorizeAdminOrOwnerOfPost] public ActionResult EditPosts(int id) { return View(); } 

Entiendo que ya ha aceptado una respuesta, y esto fue publicado hace un tiempo … (por cierto, excelente respuesta para agregar atributos personalizados), sin embargo, señalaría lo siguiente:

Si está usando este atributo una vez. En un solo método. Esta no es una buena implementación. En cambio, debes tener:

 [Authorize] // Just make sure they are auth'ed at all. public ActionResult EditPosts(int id) { Post SomePost = findPostByID (id); // However you do it - single lookup of post if (!user.IsInRole("Admin") && !{IsOwnerOfPost(post)} ) Return Not Authorized ... Edit post code here } 

Esto tiene las ventajas de:

  1. No hay clase adicional que alguien más tarde se preguntará dónde se usa.
  2. Ninguna clase que no se puede usar en ningún otro lado (no se obtiene la reutilización con un atributo personalizado)
  3. El rendimiento es mejor: solo scope del mensaje
  4. Mucho más fácil para que alguien lea / descubra cómo funciona. Sin código mágico para localizar.
  5. Y Años más tarde, cuando la clase HttpContextBase no existe, o se han perdido otras partes de los trucos utilizados para recuperar el parámetro Id, el código sigue funcionando …