首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ASP.NET MVC属性,仅允许用户编辑自己的内容

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

Stack Overflow用户
提问于 2012-06-15 00:17:15
回答 4查看 12.4K关注 0票数 20

我有一个名为Edit的控制器方法,用户可以在其中编辑他们创建的数据,如下所示...

代码语言:javascript
复制
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
}

这个方法工作得很好,但是放入每个控制器的Edit方法中就有点混乱了。每个表都有一个UserID,所以我想知道是否有一种更简单的方法可以通过[Authorize]属性或其他机制使代码更整洁。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-15 00:20:40

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

代码语言:javascript
复制
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;
    }
}

然后:

代码语言:javascript
复制
[MyAuthorize]
public ActionResult Edit(int id)
{
    // Carry out method
}

假设您需要提供这个提交实例,我们将其作为操作参数提取到自定义属性中以避免再次命中数据库,您可以执行以下操作:

代码语言:javascript
复制
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;
    }
}

然后:

代码语言:javascript
复制
[MyAuthorize]
public ActionResult Edit(Submission model)
{
    // Carry out method
}
票数 31
EN

Stack Overflow用户

发布于 2012-06-15 00:44:11

我建议您将逻辑从操作/控制器中提取出来,并构建一个域类来处理该逻辑。

Action方法实际上应该只处理从视图获取数据和向视图发送数据。您可以创建一些足够通用的东西来处理您的需求,但也将遵循单一责任原则。

代码语言:javascript
复制
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);
     }
}

这还允许您在以后灵活地允许管理员用户等操作

票数 2
EN

Stack Overflow用户

发布于 2019-03-30 19:33:39

代码语言:javascript
复制
@if (Request.IsAuthenticated && User.IsInRole("Student"))
    {
    @Html.ActionLink("Edit", "Edit", new { id = item.StdID })
    }

在我的例子中,loggedIn用户是一名学生。所以我说,如果登录请求通过了身份验证,并且他的角色是学生,那么他就可以访问编辑链接。

下面允许您让普通用户或管理员也执行编辑。

代码语言:javascript
复制
@if(Request.IsAuthenticated && User.IsInRole("Student") || 
User.IsInRole("Administrator"))
{
 @Html.ActionLink("Edit", "Edit", new { id = item.StdID })
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11037213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档