2016-11-22 134 views
0

我正在使用MVC核心的网站,我有以下问题进行整理。MVC核心授权

假设我有两个GroupA和GroupB组,这些组有一些实体。一个实体属于GroupA或GroupB--但不能同时属于这两个实体。为了保护这些实体的更新,我已经定义了以下政策:

AuthorizationOptions.AddPolicy("UpdateEntityInGroupAPolicy", policy => 
{ 
    policy.RequireClaim("ClaimThatAllowsUpdatingEntityInGroupA"); 
}); 

这项政策将确保用户,谁想要更新组A的实体有要求ClaimThatAllowsUpdatingEntityInGroupA。可以为声明ClaimThatAllowsUpdatingEntityInGroupB的GroupB创建类似的策略。

更进一步,让我们假设组A具有ID为5的实体和组B具有ID为10的实体如果给定的用户(谁的权利要求ClaimThatAllowsUpdatingEntityInGroupA,但不是要求ClaimThatAllowsUpdatingEntityInGroupB)在编号为5更新实体网址:

http://example.com/entity/5/update

我现在该如何确保用户不只是在网址更改为5〜10和B族居然更新ID是10的其他实体?

我希望我这样一个问题,并感谢您的帮助:)

回答

0

清楚,如果你想使用Authorize属性,你不能这样做,因为授权过滤器是不知道你的实体。所以,你的情况Resource Based Authorization似乎正确的路要走。

首先假设你的实体是这样的:

public class YourEntity 
{ 
    public int Id { get; set; } 
    public string Group { get; set; } 
    //... 
} 

为了实现资源基础的授权

创建一个要求:

public class UpdateRequirement : IAuthorizationRequirement 
{ 
} 

创建要求和实体

public class YourEntityAuthorizationHandler : AuthorizationHandler<UpdateRequirement, YourEntity> 
    { 
     public override Task HandleRequirementAsync(AuthorizationHandlerContext context, 
                UpdateRequirement requirement, 
                YourEntity resource) 
     { 
      if(resource.Group == "GroupA" && 
       context.User.HasClaim("ClaimThatAllowsUpdatingEntityInGroupA")) 
      { 
       context.Succeed(requirement); 
      } 
      else if(resource.Group == "GroupB" && 
       context.User.HasClaim("ClaimThatAllowsUpdatingEntityInGroupB")) 
      { 
       context.Succeed(requirement); 
      } 
      return Task.CompletedTask; 
     } 
    } 
授权处理器

最后用它在你的控制器逻辑:

public async Task<IActionResult> Update([FromServices]IAuthorizationService authorizationService, int id) 
    { 
     var entity= _entityRepository.Get(id); 

     if (entity == null) 
     { 
      return new NotFoundResult(); 
     } 

     if (await _authorizationService.AuthorizeAsync(User, entity, new UpdateRequirement())) 
     { 
      return View(entity); 
     } 
     else 
     { 
      return new ChallengeResult(); 
     } 
    } 

另见@ blowdart的example

+0

感谢您详细的解答。除此之外,我还可以阅读相同的方法,例如[这里出色的网页](http://andrewlock.net/resource-specific-authorisation-in-asp-net-core/)。我认为这是要走的路。谢谢 :) – user2711444