ASP.NET MVC - 授权重构

时间:2009-11-05 15:18:47

标签: c# asp.net-mvc asp.net-authorization

我在这段代码中看到的问题是,它会被重复使用;由经过身份验证的用户编辑/创建的任何内容(站点管理员除外)只能访问其“工作室”对象。

我向大家提出的问题;您将如何重新考虑这一因素,以便可以从客户端的知识中抽象出服务层。我打算稍后在独立的桌面应用程序中重用服务层。

请详细说明我的错误方法!我非常感激。

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

我的“用户”控制器内部将此属性附加到需要所有者的任何方法

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

现在,在我的服务层中,我正在检查传递的IPrincipal,如果它可以访问所请求的对象。 这是它变臭的地方:

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

1 个答案:

答案 0 :(得分:2)

我不确定我是否会将实际ID存储在cookie中,这有点过于暴露。我更倾向于使用Session哈希来存储数据,从而将其保存在服务器上而不会暴露。

我还使用Model(通过传递userID)来确定要返回的对象,即那些具有匹配的studioID的对象。这样你的控制器只需要调用“GetObjects(int id)”,如果他们没有访问任何东西,那么你会得到一个null或空集合。这对我来说感觉更干净。