2012-07-15 10 views
20

así que tengo mi método Acción¿Cómo implementar el atributo Autorizar personalizado para el siguiente caso?

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

En mi caso necesito para autorizar los administradores para que puedan editar mensajes, pero (aquí viene la parte buena), también necesito para permitir que el creador del mensaje para poder para 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!

+1

Puesto que usted no puede saber quien creó el cargo hasta que mirar hacia arriba. Sería mejor incluir esta lógica después de hidratar el objeto. De lo contrario, si implementa esto como un aspecto, es posible que deba buscar la publicación dos veces (una para autorización y otra para edición). –

+0

un punto bien planteado, de hecho, una vez veré si su identificación está en la entrada de función y nuevamente para hacer mi lógica de controlador. ¿Alguna idea de cómo golpear la base de datos solo una vez? – Freeman

+0

Pensando en esto un poco más, si está utilizando un buen ORM y configurando su contexto antes de la llamada de autorización (no estoy seguro acerca de esa parte), entonces debe caché en el caché de primer nivel. Entonces, no deberías ver un golpe tan pequeño en el segundo hidrato. –

Respuesta

42

Se podría escribir un atributo autorizar 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 decorar tu acción del controlador con él:

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

¡Gracias! ¡Es exactamente lo que necesitaba! – TamarG

+0

¿Por qué _ // Ahora se ha especificado id => no permitimos access_? –

+0

** Ahora veo ** que necesita cambiar: _ // Ahora se especificó id. ** Se especificó ID de NO ** .... (parece que si hay identificación no permitimos el acceso) –

Cuestiones relacionadas