【问题标题】:ASP.NET best practice for checking model's objects ownership检查模型对象所有权的 ASP.NET 最佳实践
【发布时间】:2020-07-21 11:29:51
【问题描述】:

现在我在下面的代码中检查用户的对象所有权(我注释了代码的重要部分)。而且我对应用程序中的每个模型和每个控制器方法都这样做,这完全违反了DRY 原则。也许你有一些想法可以避免重复?

此外,我不确定它是否安全,并且用户将无法通过一些技巧访问其他人的数据。我正在做的事情安全吗?

这是关于个人数据安全的一个非常重要的话题,我相信应该有某种文档。不幸的是,我没有找到任何文档,如果我没有很好地搜索,我会很高兴看到任何链接。

TasksController.cs

public async Task<IActionResult> Index()
        {
            // here I form a selection from objects belonging to the current user
            var Tasks = _context.Tasks.Where(t => t.UserId.Equals(User.Identity.GetUserId()));
            return View(await applicationDbContext.ToListAsync());
        }


public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var task = await _context.Tasks.FindAsync(id);

            // here I check if the requested object belongs to the current user
            if (task == null | task.UserId != User.Identity.GetUserId())
            {
                return NotFound();
            }
            return View(task);
        }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,Name,TaskTypeId,Status,UserId")] Task task)
    {
        if (ModelState.IsValid)
        {
            // here i am assigning object's UserId to id of current user
            task.UserId = User.Identity.GetUserId();
            _context.Add(task);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(task);
    }

【问题讨论】:

    标签: asp.net-mvc asp.net-core


    【解决方案1】:

    我认为最好的方法是将工作上下文对象注入控制器。然后从该对象中获取用户和其他常见信息,这将减少重复代码。例如:

    控制器:

    private readonly IWorkContext _workContext;
    
    public MyController(IWorkContext  workContext)
    {
     this._workContext = workContext;
    }
    

    行动:

    你用_workContext.UserId代替User.Identity.GetUserId()。这样,如果您的身份逻辑发生变化,那么您不必在数百个地方进行更改,而只需在 IWorkContext 中进行更改。

    下面是 IworkContext 实现中的内容:

    public partial class WorkContext : IWorkContext
    {
        ...
        public virtual string UserId
            {
                get
                {
                    return User.Identity.GetUserId()
                }
            }
    }
    

    您可以相应地定义IWorkContext 接口并在其中实现必要的基于用户的逻辑。

    您还可以在工作上下文对象中而不是在不同的操作中使用Task 属性。

    我没有包含上面的依赖注入相关的代码示例。这不是问题的一部分。你可以阅读更多关于依赖注入here的内容。

    【讨论】:

    • 很高兴它有帮助。希望你也不介意投票:)干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 2011-04-08
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多