Question

Le problème que je vois avec ce code, est qu'il va être réutilisé beaucoup; quoi que ce soit en cours d'édition / créé par un utilisateur authentifié (sauf pour les administrateurs du site) ne pourront avoir accès à un leurs objets « studios ».

Ma question à vous tous; comment voulez-vous re-facteur de cette sorte que la couche de service peut être prélevée loin de la connaissance du client. Je compte réutiliser la couche de service dans une application de bureau autonome plus tard.

S'il vous plaît faire la lumière sur mes voies erronées! Je vous remercie vivement.

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;
}

À l'intérieur de mon contrôleur « Utilisateur » attach cet attribut à toute méthode qui nécessite un propriétaire

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

Maintenant, dans ma couche de service est l'endroit où je vérifie le passé vers le bas IPrincipal si elle a accès à l'objet demandé. C'est là ça devient nauséabond:

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");
    }
Était-ce utile?

La solution

Je ne suis pas sûr que je serais maintenant les identifiants réels dans le cookie, qui est un peu trop exposé. Je serais plus enclin à utiliser le hachage de session pour stocker les données ainsi garder sur le serveur et non exposé.

Je l'utilise aussi le modèle (en passant le userID) pour déterminer les objets à revenir, à savoir ceux qui ont un studioID correspondant. De cette façon, votre contrôleur ne serait jamais à appeler « getObjects (int id) », si elles n'ont pas accès à quoi que ce soit alors vous obtenez une collection vide ou null retour. Cela se sent me plus propre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top