MVC 6仅授权所有者或管理员

时间:2016-07-11 14:18:09

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

我有一个可以拥有多个项目的用户。 我希望每个人都能看到这些项目,但只有创建它的用户或管理员才能编辑它。

我更改了模板提供的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中执行此操作的方法吗?

0 个答案:

没有答案