安全访问部分属性

时间:2017-07-05 13:27:41

标签: c# asp.net asp.net-mvc entity-framework .net-core

在我的应用程序中,我有两个角色(adminnormal)。在模型中我有类(示例):

public class Foo
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Extra { get; set; }
}

用户还可以编辑该对象并使用过滤器进行搜索。应用程序基于带有EF Core的WebAPI ASP.NET Core。

要求normal不应该看到(或对其执行任何操作)Extra属性。我应该通过拆分模型类(或其他东西)来保护应用程序(服务,控制器,数据访问层)中的数据,还是通过忽略属性来格式化端点输出?

我的一个想法是创建一个属性,将其放在Extra属性上,然后使用ContractResolver在用户没有资格查看该属性时忽略具有该属性的属性。同时修改EF更改跟踪器以忽略保存该属性(在相同情况下)。

是否有任何模式或策略如何处理该问题?

1 个答案:

答案 0 :(得分:0)

没有内置的机制,不,因为它太精细了。此外,尝试在EF级别强制执行此操作意味着将您的HttpContext泄露到您的DAL中,出于多种原因这是一个坏主意。

我最好的建议是使用继承对其进行建模。换句话说,创建类似的东西:

public class Foo
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }
}

public class ExtraFoo : Foo
{
    public string Extra { get; set; }
}

默认情况下,Entity Framework将通过单表继承实现此功能,因此您的支持表看起来几乎完全相同。但是,这使您能够单独使用其中一个。

然后,我建议使用完全独立的控制器和/或操作来处理每种类型。这允许您为每个用户使用不同的授权,确保“普通”用户只能使用Foo(而不是ExtraFoo)。为了否定明显的重复,这意味着,你可以使用一个基本控制器,利用泛型,每个类型特定的控制器可以继承:

public class BaseFooController<TFoo> : Controller
    where TFoo : Foo, new()
{
    // all your actions here, utilizing generic type, e.g.:

    [HttpPost]
    public ActionResult Create(TFoo foo)
    {
        ...
    }
}

[Authorize(Roles = "normal")]
public class FooController : BaseFooController<Foo>
{
}

[Authorize(Roles = "admin")]
public class ExtraFooController : BaseFooController<ExtraFoo>
{
}