ASP.NET MVC属性只允许用户编辑自己的内容

Ste*_*aly 18 .net c# security authentication asp.net-mvc

我有一个调用的控制器方法Edit,用户可以编辑他们创建的数据,如此...

public ActionResult Edit(int id)
{
    Submission submission = unit.SubmissionRepository.GetByID(id);
    User user = unit.UserRepository.GetByUsername(User.Identity.Name);

    //Make sure the submission belongs to the user
    if (submission.UserID != user.UserID)
    {
        throw new SecurityException("Unauthorized access!");
    }

    //Carry out method
}
Run Code Online (Sandbox Code Playgroud)

这种方法工作正常,但是放入每个控制器的Edit方法都有点乱.每个表总是有一个,UserID所以我想知道是否有一种更简单的方法来通过[Authorize]属性或其他机制自动化这个代码更清洁.

Dar*_*rov 28

是的,您可以通过自定义Authorize属性实现此目的:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var rd = httpContext.Request.RequestContext.RouteData;

        var id = rd.Values["id"];
        var userName = httpContext.User.Identity.Name;

        Submission submission = unit.SubmissionRepository.GetByID(id);
        User user = unit.UserRepository.GetByUsername(userName);

        return submission.UserID == user.UserID;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

[MyAuthorize]
public ActionResult Edit(int id)
{
    // Carry out method
}
Run Code Online (Sandbox Code Playgroud)

我们假设您需要将我们提取的提交实例作为操作参数提供给自定义属性,以避免再次访问数据库,您可以执行以下操作:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var rd = httpContext.Request.RequestContext.RouteData;

        var id = rd.Values["id"];
        var userName = httpContext.User.Identity.Name;

        Submission submission = unit.SubmissionRepository.GetByID(id);
        User user = unit.UserRepository.GetByUsername(userName);

        rd.Values["model"] = submission;

        return submission.UserID == user.UserID;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

[MyAuthorize]
public ActionResult Edit(Submission model)
{
    // Carry out method
}
Run Code Online (Sandbox Code Playgroud)