【问题标题】:Help me decide whether to use ASP.NET default membership/roles providers or write custom providers帮助我决定是使用 ASP.NET 默认成员资格/角色提供程序还是编写自定义提供程序
【发布时间】:2010-10-06 14:37:17
【问题描述】:

我昨天花了很大一部分时间阅读这个主题,但仍然觉得我不确定该走哪条路。在身份验证和授权方面,我来自“自己动手”的背景。我们从未使用过 Forms 身份验证,更不用说 Membership API。查看我们的旧代码,我们将使用会话变量来捕获/控制用户是否登录等。在我即将进行的这个新项目中,我想让我们回到开始时应该做的事情的正轨,这是使用框架提供的工具。

我已经有一个我将要使用的数据库架构,但它并不是一成不变的;如有必要,我可以对其进行更改。在这个模式中已经有一个用户表,它使用一个整数作为主键。此表还包含其他信息,例如名字和姓氏。我还有基于 UserId 的外键到其他表,例如电话和地址。下面我概述了我想到的一些优点/缺点。

默认提供者

优点

  • 代码更少。
  • 能够利用所有相关的服务器控件,例如登录、更改密码。

缺点

  • 开箱即用的某些控件可能对我没有用处。例如 CreateUserWizard,我可能需要在用户创建期间捕获其他信息,例如关联表的电话和地址信息。不确定这是否会使这个控件对我毫无用处。
  • 我必须在我的关联表(电话、地址)中为默认提供程序中的 GUID 的 UserId 创建外键。
  • 如果我确实创建了这些外键约束并且不使用级联删除;我还需要删除外键表中的关联行。可能不得不利用诸如 TransactionScope 对象之类的东西来确保所有这些都是原子操作。

自定义提供程序

优点

  • 能够利用现有架构表。
  • 更容易将身份验证/授权提取到服务中。

缺点

  • 必须自己为大多数/所有事情提供实施。
  • 要使用任何控件,我必须在提供程序中提供它们所需的实现。

可能还有其他一些事情我还没有考虑过,因为我以前从未使用过它,这也让我有点不舒服。

谢谢。

【问题讨论】:

    标签: c# .net asp.net asp.net-membership


    【解决方案1】:

    我最近不得不做出同样的选择,并决定创建一个自定义提供程序。

    我这样做的最大原因归结为默认的数据库架构。所有默认的 db 对象都是在 dbo 模式中创建的,并以“aspnet_”或“vw_aspnet”等为前缀。对我来说,这是一个真正的关闭。如果您还没有看到它们,请运行 aspnet_regsql.exe 来创建它们。

    另外,Steven Sanderson 在 Pro ASP.NET MVC 2 Framework 中这样说:

    ...SqlProfileProvider 使用了一种特别恶心的数据库模式,其中配置文件条目存储为以冒号分隔的名称/值对,因此基本上无法查询。

    总体而言,由于关注点清晰分离、跨项目重用以及与 ASP.NET 的其余部分集成,因此值得遵循 API,但您只想将内置的 SQL 存储提供程序用于小型或一次性项目。

    我还没有完成创建自定义提供程序的整个过程(我在使用 Azure 表存储时做了部分实现),但我计划将来在多个项目中使用这些提供程序,所以我觉得这些努力是值得的。

    【讨论】:

    • 我也倾向于这种方式,架构对我来说似乎非常有限。我真的不想将他们的 GUID 用作外键。无论如何我都必须在应用程序中编写自己的管理屏幕(管理员用户可以创建其他用户等),这一事实使我相信使用默认设置的好处将是微乎其微的。基本上我唯一失去的是密码恢复等的默认实现。
    • 您提出了另一个不使用默认提供程序的好理由。最后,默认模式只会在我的应用程序上显得格格不入,不适合我的数据库模式的其余部分,而且我总是担心会遇到隐藏的陷阱,就像上面提到的配置文件条目的存储方式一样。
    • 个人资料提供者几乎一文不值,但完全是可选的,所以我不会反对会员提供者。
    【解决方案2】:

    如果您正在构建一个新应用程序,我会毫不犹豫地使用 asp.net 默认提供程序。您始终可以决定不使用默认控件并以编程方式创建自己的控件。您还可以通过使用任何开源预先创建的用户管理工具来节省大量时间。同时,您始终可以将包含的信息扩展到默认表中。

    【讨论】:

      【解决方案3】:

      就个人而言,我将 SqlMembershipProvider 用作独立实体,而我的数据库的其余部分位于 Oracle 中。我从不查看数据库,所以名称和 GUID 不会打扰我(看不见,心不在焉)。它开箱即用,非常棒!

      在我的场景中,我在 Oracle 数据库中有一个用户表,我在创建/删除成员用户(无 GUID)时插入/删除该表。我认为成员数据库是“主”记录,而 Oracle 表基本上是为了支持表的引用完整性。它并没有真正在官方事务中完成,但我使用 try/catch 来保持它们足够好地同步。

      角色提供者确实是有限的,如果您想要任何类型的分层或动态角色,那么您就大功告成了。但它是一个与会员完全隔离的独立系统,您不必使用它。

      控件还不错。它们中的很多都支持模板,因此您可以向它们添加自己的控件,并有很多事件可以挂接到它们中。不要害怕滚动自己的控件,但首先要给默认控件一个机会。 Membership API 的易用性确实有助于创建这些控件。

      【讨论】:

      • 谢谢 Greg,我会考虑所有这些。有趣的是你提到了角色位......我的用户将属于不同的组,例如银行家、经纪人,在每个组下我会有管理员、标准等。它不是完全动态的或非常分层的,但我不知道角色提供者是否是对此有好处。我总是可以将用户添加到两个“角色”,其中一个是“银行家”,另一个是“管理员”,尽管这对我来说似乎很愚蠢。
      • 我在类似的情况下使用了 RoleProvider。 BankerAdmin、BankerStandard、BrokerAdmin、BrokerStandard 等是我的角色。当您需要有关哪个角色可以在哪个角色中创建用户的规则时,就会出现问题。角色提供者没有办法说“BankerAdmin”可以编辑“BankerStandard”的用户帐户。
      • 我想可以在数据库中添加额外的表来管理这种类型的关系。或者我想我总是可以把它融入到业务逻辑中,对吧?如果 BankerAdmin 则允许编辑 BankerStandard。当然,现在我失去了按原样使用 API 的许多好处。
      • 好吧,我的要求从“你是 BankerStandard”变成了“你是账户 #1 和 #3 的 BankerStandard”,此时我完全放弃了角色提供者,只是建立了自己的系统,但我仍在使用会员服务提供商。
      【解决方案4】:

      就个人而言,我会选择框架提供的内容。在这种情况下,没有理由滚动您自己的身份验证。

      过去,您可能想自己做事,但现在没有理由这样做。

      我认为,如果您尝试自己编写此代码,您将重新创建轮子,并且需要花费太多时间和资源才能使其正确。尤其是在处理安全问题时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-30
        • 1970-01-01
        相关资源
        最近更新 更多