Frage

Das Problem, das ich mit diesem Code zu sehen ist, dass es eine Menge wiederverwendet werden wird; alles wird von einem authentifizierten Benutzer bearbeitet / erstellt (außer für Site-Administratoren) nur Zugang zu einem ihrer „Studios“ Objekte.

Meine Frage an euch alle; wie würden Sie wieder Faktor dies so kann die Service-Schicht weg von dem Wissen des Kunden abstrahiert werden. Ich beabsichtige, später die Dienstschicht in einer eigenständigen Desktop-Anwendung wiederverwendet werden.

Bitte werfen ein Licht auf meine Irrwege! Ich schätze es sehr.

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

Innerhalb meiner „User“-Controller dieses Attribut auf jedes Verfahren anschließen, die einen Besitzer erfordert

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

Nun, in meiner Dienstschicht ist, wo ich die überliefert IPrincipal ich überprüfen, ob es Zugriff auf das Objekt hat angefordert wird. Dies ist, wo es wird immer stinkende:

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");
    }
War es hilfreich?

Lösung

Ich bin nicht sicher, würde ich die tatsächlichen IDs im Cookie wird die Speicherung, das ist ein wenig zu ausgesetzt. Ich wäre eher geneigt, die Session-Hash zu verwenden, die Daten zu speichern, damit es auf dem Server zu halten und nicht ausgesetzt.

Ich würde auch das Modell verwenden (durch die userID vorbei) zu bestimmen, die zurück Objekte, das heißt diejenigen, die einen entsprechenden studioID haben. Auf diese Weise Ihren Controller würde immer nur anrufen müssen „GetObjects (int id)“, wenn sie Zugang zu etwas nicht haben, dann erhalten Sie eine Null oder leere Auflistung zurück. Das fühlt sich sauberer zu mir.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top