【问题标题】:ASP.NET Core Custom Policy Based Authorization - unclear基于 ASP.NET Core 自定义策略的授权 - 不清楚
【发布时间】:2017-07-30 14:25:20
【问题描述】:

好的,ASP.NET Core 中基于自定义策略的授权。我有点理解这个新身份框架的想法,但仍然不是 100% 清楚你可以用这个实现什么。假设我们在 HomeController 中有一个名为 List 的 Action。此操作将查询并显示数据库中的产品列表。必须访问此列表的用户必须是营销部门的一部分。因此,在我们的政策中,我们检查用户是否有名为 Division 的索赔,其价值是 Marketing。如果是,那么他将被允许查看列表,否则不允许。我们可以这样装饰我们的动作:

[Authorize(Policy = "ProductsAccess")]
public IActionResult List()  
{
    //do query and return the products view model
    return View();
}

这一切都很好。它会完美运行。

场景 1: 如果我想在产品级别添加策略,并且基于该策略,用户将只能看到他所在部门的产品。所以营销人员会看到他的产品,研发人员会看到他的等等。我怎样才能做到这一点?可以通过政策完成吗?如果是怎么办?

场景 2: 现场级别的访问权限如何?假设我想隐藏某些字段?示例:所有产品都有某些列必须对经理可见而对其他用户隐藏?这可以使用自定义策略来完成吗?如果是怎么办?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-identity


    【解决方案1】:

    对于场景1,您可以使用resource based authorization

    本质上,您会将IAuthorizationService 注入您的服务或控制器,然后拥有一个或多个授权处理程序,这些授权处理程序派生出AuthorizationHandler<TRequirement, TDocument>,然后调用

    if(await _authorizationService.AuthorizeAsync(User, document, "MyPolicy"))
    {
        // Success, user has access to it
    }
    

    缺点:您必须从数据库中获取所有产品,然后在内存中进行过滤,因此它适用于不需要分页的单个文档或较小的数据。即使在较小的数据上,分页也会破坏它(即,如果您请求 50 个产品,但用户无权访问其中的 40 个,尽管页面大小为 50,但只会返回 10 个)。

    EF Core 2.0 可以使用替代方案(如果您使用 EF Core 作为 ORM)。您可以添加全局过滤器,它将应用于对某个实体的所有查询。

    更多信息请见Entity Framework Core 2.0 Announcement博文:

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    
        public int TenantId {get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Post>()
                .HasQueryFilter(p => !p.IsDeleted &&
                      p.TenantId == this.TenantId );
        }
    }
    

    它可能适合也可能不适合您的情况,这取决于您是否有可以使用的行级数据(即某种“资源所有者”字段)。

    场景 2 据我所知,Identity 不可能开箱即用,您必须自己实现一些东西,但这是一个非常复杂的主题(如果您曾经工作过有了 Dynamics CRM,你就明白我的意思了)。

    更新

    为了快速实现,您可以尝试将您的响应包装在 ExpandoObject 周围(这是您使用 dynamic 关键字时使用的底层内容)并对其进行迭代,删除用户无权访问的属性在从控制器操作返回之前或编写一个授权过滤器,它将自动为特定或所有控制器执行此操作。

    对于一个粗略的想法(关于如何构造/使用 expando 对象),请参阅我的回答 here

    【讨论】:

      【解决方案2】:

      我不认为政策旨在解决您的案件。我不确定这是否可能,即使可能,我觉得代码本身也会受到它带来的复杂性和混乱的影响。我不会给我的授权过滤器那么大的责任。

      对于第二种情况,您可以根据当前用户的角色、声明或其他内容跳过在视图中输出某些数据。用策略解决这个问题似乎不必要地复杂。

      为它的用途使用策略,授权用户是否被允许运行一个方法。与返回的内容有何不同?在正常的代码流中处理它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-28
        • 2021-11-07
        • 2016-09-13
        • 1970-01-01
        • 1970-01-01
        • 2019-12-31
        相关资源
        最近更新 更多