Domanda

Il problema che vedo con questo codice, è che si sta per essere riutilizzato un sacco;nulla è stato modificato/creato da un utente autenticato (tranne che per gli amministratori del Sito hanno accesso a una loro "studios" di oggetti.

La mia domanda a tutti voi;come si ri-fattore questo modo il livello di servizio può essere astratta dalla conoscenza del cliente.Ho intenzione di riutilizzare il livello di servizio in un stand-alone applicazione desktop più tardi.

Si prega di far luce sul mio modi errati!Lo apprezzo molto.

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

All'interno del mio "Utente" Controller di collegare questa attributo per ogni metodo che richiede un proprietario

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

Ora, nel mio livello di Servizio è dove sto controllando il tramandata IPrincipal se si ha accesso all'oggetto richiesto. Questo è dove è sempre puzzolente:

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");
    }
È stato utile?

Soluzione

Io non sono sicuro che mi piacerebbe essere la memorizzazione effettiva Id cookie, che è un po ' troppo esposto.Io sarei più propenso a usare l'hash di Sessione per memorizzare i dati in modo da mantenere sul server e non esposti.

Vorrei anche utilizzare il Modello (passando l'id utente) per determinare quali oggetti di ritorno, vale a direcoloro che hanno una corrispondenza studioID.In questo modo il tuo controller avrebbe mai chiamare "GetObjects(int id)", se non hanno accesso a nulla allora si ottiene un valore null o vuoto insieme.Che si sente pulitore per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top