ASP.NET MVC属性只能让用户编辑他/她自己的内容(ASP.NET MVC Attribute

2019-06-25 11:53发布

我有一个名为控制器方法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
}

此方法适用罚款不过是有点乱摆在每个控制器编辑方法。 每个表始终有一个UserID ,所以我想知道是否有通过自动执行此更简单的方法[Authorize]属性或一些其他机制来使代码更干净。

Answer 1:

是的,你可以做到这一点通过自定义授权属性:

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

然后:

[MyAuthorize]
public ActionResult Edit(int id)
{
    // Carry out method
}

让我们假设你需要养活,我们提取到自定义属性的动作参数此提交实例,以避免击中数据库再次,你可以做到以下几点:

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

然后:

[MyAuthorize]
public ActionResult Edit(Submission model)
{
    // Carry out method
}


Answer 2:

我建议你拉出来的逻辑动作/控制器,并建立一个域类来处理逻辑。

操作方法真的应该只处理从得到的数据和发送数据到视图。 你可以创建一些通用的,足以应付您的需求,也将遵循单一的责任主体。

public class AuthorizedToEdit 
{
     protected override bool AuthorizeCore(string user, int itemId)
     {
         var userName = httpContext.User.Identity.Name;

         var authUsers = SubmissionRepository.GetAuthoriedUsers(itemId);

         return authUsers.Contains(user);
     }
}

这也将让您可以灵活后来就允许类似于admin用户



Answer 3:

@if (Request.IsAuthenticated && User.IsInRole("Student"))
    {
    @Html.ActionLink("Edit", "Edit", new { id = item.StdID })
    }

在我的情况下,用户的loggedIn是学生。 所以我说,如果登录请求进行认证,如果他的角色是学生,然后让链接编辑是他访问。

下面这使您可以让普通用户或管理员进行编辑也。

@if(Request.IsAuthenticated && User.IsInRole("Student") || 
User.IsInRole("Administrator"))
{
 @Html.ActionLink("Edit", "Edit", new { id = item.StdID })
}


Answer 4:

我建议在阅读了AuthorizeAttribute (见这里 )。 此外,你见过这个帖子? 它提供了如何重写认证属性内脏以及如何使用的IPrincipal和IIdentity的。



文章来源: ASP.NET MVC Attribute to only let user edit his/her own content