Pregunta

El problema que veo con este código, es que va a volver a utilizar una gran cantidad; nada está editando / creado por un usuario autenticado (excepto para los administradores del sitio) sólo tiene acceso a una de sus objetos "estudios".

Mi pregunta a todos ustedes; ¿cómo se re-factor de este modo la capa de servicio se puede abstraer lejos del conocimiento del cliente. Tengo la intención de volver a utilizar la capa de servicio en una aplicación de escritorio independiente después.

Por favor, arrojar algo de luz sobre mis caminos erróneos! Aprecio grandemente.

AuthorizeOwnerAttribute.cs (AuthorizeAttribute)

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = httpContext.Request.Cookies[cookieName];

    // If the cookie can't be found, don't issue the ticket
    if (authCookie == null) return false;

    // Get the authentication ticket and rebuild the principal & identity
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    string[] userData = authTicket.UserData.Split(new[] { '|' });

    int userId = Int32.Parse(userData[0]);
    int studioID = Int32.Parse(userData[1]);
    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
    WebPrincipal userPrincipal = new WebPrincipal(userIdentity, userId, studioID);
    httpContext.User = userPrincipal;

    return true;
}

Dentro de mi "Usuario" Controlador adjuntar este atributo a cualquier método que requiere un propietario

    [AuthorizeOwner]
    public ActionResult Edit(int Id)
    {
        IUser user = userService.GetById(HttpContext.User, Id);
        return View(user);
    }

Ahora, en mi servicio capa es donde yo estoy comprobando el pasado abajo IPrincipal si tiene acceso al objeto que se solicita. Esto es donde se está haciendo mal olor:

UserService.cs

    public IUser GetById(IPrincipal authUser, int id)
    {
        if (authUser == null) throw new ArgumentException("user");

        WebPrincipal webPrincipal = authUser as WebPrincipal;
        if (webPrincipal == null) throw new AuthenticationException("User is not logged in");

        IUser user = repository.GetByID(id).FirstOrDefault();
        if (user != null)
        {
            if (user.StudioID != webPrincipal.StudioID) throw new AuthenticationException("User does not have ownership of this object");
            return user;
        }

        throw new ArgumentException("Couldn't find a user by the id specified", "id");
    }
¿Fue útil?

Solución

No estoy seguro de que estaría almacenando los identificadores reales en la cookie, que es un poco demasiado expuesta. Yo estaría más inclinado a usar el hash de sesión para almacenar los datos que lo que mantiene en el servidor y no expuestos.

Me gustaría también utilizar el modelo (pasando el ID de usuario) para determinar qué objetos para volver, es decir, aquellos que tienen un studioID coincidente. De esa manera su controlador sería sólo tenga que llamar "getObjects (int id)", si no tienen acceso a nada, entonces se obtiene una colección nulo o vacío espalda. Eso se siente más limpio para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top