【问题标题】:POCO + Entity Framework with repository pattern - permission handlingPOCO + 具有存储库模式的实体框架 - 权限处理
【发布时间】:2011-04-02 14:31:14
【问题描述】:

我有一个由 3 层组成的应用程序:
UI:要在 ASP.NET MVC 中实现
业务:保存业务逻辑和资源访问控制
存储库 (DAL):使用存储库模式通过 POCO 对象和 EF 实现。我的 POCO 对象与上层共享。

我对 POCO 应该拥有哪些信息/方法有疑问? 即:如果我有一个包含用户用户名和密码的用户表,我的 POCO 应该有什么?我应该如何验证密码?我的 POCO 是否应该有一种方法要求存储库进行验证?

另外,我应该如何控制对我的资源的访问?我的存储库是否应该控制谁可以和不能访问资源?这仍然让我的 POCO 使用导航属性公开信息。如果当前用户也可以使用它们,我应该检查 POCO 属性吗?

提前致谢。

【问题讨论】:

    标签: entity-framework permissions authorization repository-pattern poco


    【解决方案1】:

    我有一个类似的项目,我可以向您详细介绍我是如何执行类似操作的。我假设您的整个解决方案都是基于 .Net 的。

    POCO(Plain Old CLR Objects)就是没有业务逻辑的对象。因此,密码验证不应直接在该类中,而应在您的业务层中。例如,UI 会调用控制器操作将数据提交给业务层(BL),BL 会通过调用存储库来执行用户密码验证以获取当前存储/加密的密码,BL 将比较密码并返回一个结果到您的 UI 或采取一些其他措施。当然,所有数据都应该经过验证,以防止 SQL 注入或跨站点脚本攻击等事件。

    您的 POCO 可以具有 Uid/Pwd 属性。你应该在你的应用层之间传递这个 POCO 对象。因此,MVC UI 将绑定到您的用户对象,并且在提交时,控制器将调用您的 BL 中的某个方法并在该用户对象上执行和业务规则(密码有效)。为了在实际层之间传递这些,您需要从主 DAL 中提取这些 POCO,并将它们放在单独的组件中。这些对象通常称为域对象,您可以在 Google 域驱动开发中获取有关该方法的更多信息。

    可以在应用程序中以多种不同的方式实现安全性,这完全取决于您想要覆盖的项目的深度。 MVC 中最基本的方法是在您的控制器类上使用 Authorize 属性(谷歌:保护您的控制器操作)。当您的用户通过身份验证后,可以为他们分配某种类型的应用程序角色,您可以使用以下格式验证用户是否具有这些角色之一:

    [Authorize(Roles = "ModifyUserRoles")]
            public ActionResult About()
            {
    }
    

    【讨论】:

    • 感谢您的提示,它们很有用:) 但是关于访问控制,我不希望我的 UI 对此负责。如果我更改 UI,我将失去访问控制,这就是为什么我希望它位于其他地方。我的信息将在未来通过网站 (asp.net mvc) 和 REST 服务访问。
    • 如果您将来要拥有多个界面,我强烈建议在您的 UI 和 BL 之间添加一个“服务”层。这将有助于您将来切换或添加多个 UI。在这种情况下,您可以将此授权逻辑移动到 WCF 服务层中。这方面也有很多文章。希望这会有所帮助:)
    【解决方案2】:

    如果您的上下文返回用户对象,则选择将“验证”密码:

    public User GetUser(string login, string password)
    {
    //...code to set up context var...
    var user = (from o in context.Users.OfType<User>() where o.UserID == login && o.Password == password) select o).FirstOrDefault();
    //...maybe more code...
    }
    

    如何加密密码以及如何处理登录失败(方法返回 null)应该取决于您的业务层。

    就我个人而言,我认为任何业务逻辑都不应该包含在您的 DAL 中。确定谁有权访问业务层执行的最佳功能,但您可以禁用延迟加载并仅包含基于用户的导航属性,或者您可以在需要时对这些属性提出额外请求。返回的数据量和类型(出于性能原因)将推动该决定。

    【讨论】:

    • 那么,您是说我的业务层应该调用存储库来验证用户? “仅包括基于用户的导航属性”,我不明白这一点。你能再清楚一点吗?谢谢
    • 我的意思是,如果您想按用户进行限制,您可以根据用户/用户类型排除/包含导航属性/其他属性,但您的业务/服务层是真正的应实施逻辑/安全性。在我们的情况下,我扩展了 POCO 部分类并添加了一个 IsValid 布尔值。该代码将返回的(加密的)密码与提供的加密密码进行比较,以确定身份验证是否有效,然后更新登录尝试计数器。 BL 根据其他规则决定如何处理无效的登录尝试。
    【解决方案3】:

    我认为并不总是需要通过层传递你的 POCO 对象(域对象),例如在你的情况下,视图层只需要一个简单的视图模型,只有用户名和密码属性并将其传递给 BL ,您的 BL 将通过存储库获取 User 域对象,并根据从 View 层收到的内容验证密码。

    【讨论】:

      猜你喜欢
      • 2011-06-06
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多