我有一个可以拥有多个项目的用户。 我希望每个人都能看到这些项目,但只有创建它的用户或管理员才能编辑它。
我更改了模板提供的ApplicationUser类。
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
在Project类中,我保存创建它的用户。
public class Project
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
然后,如果当前用户是他想要更改的项目的所有者,我会检查每个方法。
// GET: Projects/Edit/5
[Authorize]
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
ApplicationUser user = await GetCurrentUserAsync();
Project project = _context.Project.Single(m => m.Id == id);
if (project == null)
{
return HttpNotFound();
}else if(project.ApplicationUser != user)
{
return HttpNotFound();
}
return View(project);
}
有更好的方法吗? 我在MVC 5中看到你有AuthorizationAttribute,但它不再可用。
这样的事情会很棒,但我甚至不知道从哪里开始:
[OwnerAuthorize]
public IActionResult Edit(int? id)
编辑:
我在阅读https://docs.asp.net/en/latest/security/authorization/resourcebased.html
后设法找到了这样做的方法public class ProjectAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Project>
{
private readonly UserManager<ApplicationUser> _userManager;
public ProjectAuthorizationHandler(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, Project resource)
{
var userId = _userManager.GetUserId(context.User);
if(userId != null && resource.OwnerId == userId)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
在控制器中
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var project = await _context.Project.SingleOrDefaultAsync(m => m.Id == id);
if (project == null)
{
return NotFound();
}
if (!await _authorizationService.AuthorizeAsync(User, project, Operations.Update))
{
return Forbid();
}
return View(project);
}
它有效,但我唯一不理解的是我应该如何处理HandleRequirementAsync方法中的要求。
这是在MVC 6中执行此操作的方法吗?