提问人:Alireza Ahmadi 提问时间:4/20/2023 最后编辑:Ivan GechevAlireza Ahmadi 更新时间:4/21/2023 访问量:44
用户能够编辑不属于同一用户的其他实体,如何防止此操作?
user is able to edit other entity that is not for the same user, how can I prevent from this action?
问:
我正在为我的应用程序使用,当用户通过身份验证时,用户可以编辑和更改 url 中的参数,并且用户能够更改和编辑其他用户的数据,为了解决这个问题,我使用此解决方案:FormsAuthentication
ID
[Authorize]
public ActionResult UserInfo(long id)
{
var userViewModel = _userService.GetUserById(id);
** if (userViewModel.Username != HttpContext.User.Identity.Name)
throw new UnauthorizedAccessException("we are not allowed to show other users' information to you");**
return View(userViewModel);
}
但这不是一个好的解决方案,因为有了这个,我必须检查所有操作的相同逻辑,以检查用户是否正在编辑他/她自己的数据
如何使用 dbContext 和其中的 AOP 解决方案解决它?SaveChanges()
我的用户类:
public string Username { get; private set; }
public string Password { get; private set; }
public string Name { get; private set; }
public DateTime? BirthDate { get; private set; }
public List<WishList.WishList> WishLists { get; private set; }
其他课程:
public string Title { get; private set; }
public string Description { get; private set; }
public List<WishListItem.WishListItem> WishListItems { get; private set; }
public User.User User { get; private set; }
public long UserId { get; private set; }
public string Title { get; private set; }
public decimal RoughPrice { get; private set; }
public int Priority { get; private set; }
public WishList.WishList WishList { get; private set; }
public long WishListId { get; private set; }
我的 DbContext:
public class WishListManagementDbContext : System.Data.Entity.DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<BaseEntity> BaseEntities { get; set; }
public DbSet<WishListItem> WishListItems { get; set; }
public DbSet<WishList> WishLists { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.AddFromAssembly(typeof(WishListManagementDbContext).Assembly);
base.OnModelCreating(modelBuilder);
}
}
如果你能帮助我,我将不胜感激。
答:
1赞
Bruno Lazzara
4/21/2023
#1
无需在每个操作中编写此代码的一种可能方法是使用全局筛选器。它将在应用的每个操作调用时自动执行。
创建一个派生自 和 的类,并重写该方法。所以,就你的情况而言,它是这样的:ActionFilterAttribute
IActionFilter
OnActionExecuting
using Microsoft.AspNetCore.Mvc.Filters;
public class MyGlobalActionFilter : ActionFilterAttribute, IActionFilter
{
//I am assuming you used DI for the service, so you can use it here too
private readonly UserService _userService;
public MyGlobalActionFilter(UserService userService)
{
_userService = userService;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var userViewModel = _userService.GetUserById(id);
if (userViewModel.Username != HttpContext.User.Identity.Name)
throw new UnauthorizedAccessException("we are not allowed to show other users' information to you");
}
}
然后将其添加到您的文件中:Program.cs
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add<MyGlobalActionFilter>();
});
评论
0赞
Alireza Ahmadi
4/22/2023
感谢您的回答,这可以帮助我,但实际上,我想用 AOP 解决方案解决这个问题,并且不想在每个操作中调用过滤器,我想覆盖 DbContext 类的 SaveChange() 方法,以便所有操作都会自动读取该代码,我不需要自己在每个操作中调用我的自定义过滤器
0赞
Bruno Lazzara
4/22/2023
当您在 Program.cs 文件中添加筛选器时,正如我在答案的最后一部分中提到的,它将在每个操作时自动调用,无需执行任何其他操作。这与重写 SaveChanges() 类似,您将编写将在每次调用时自动执行的代码
0赞
Alireza Ahmadi
4/24/2023
哦,现在我明白了,我也可以在框架 in.NET 使用它吗?
1赞
Bruno Lazzara
4/24/2023
是的, 你可以的。查看此链接 tutorialsteacher.com/mvc/filters-in-asp.net-mvc
评论