*不*使用 asp.net 会员提供程序是个坏主意吗?

Posted

技术标签:

【中文标题】*不*使用 asp.net 会员提供程序是个坏主意吗?【英文标题】:Is *not* using the asp.net membership provider a bad idea? 【发布时间】:2011-02-27 11:35:27 【问题描述】:

使用内置的 asp.net 会员提供程序通常是一个非常糟糕的主意吗?

我一直为我的 asp.net 应用程序(面向公众)推出自己的应用程序,并且这样做确实没有任何问题。它有效,并且似乎避免了一层复杂性。我的需求非常基本:一旦设置,用户必须使用电子邮件地址和密码登录,如果他们忘记了,它将通过电子邮件发送给他们(一个新的)。设置后,每个用户帐户几乎不需要做任何事情,但我确实需要为每个用户存储几个额外的字段(全名、电话和其他一些字段等)。需要登录凭据的用户数量很少(通常只有管理员和一些备份),其他所有人都未经身份验证使用该站点。

跳过 asp.net 会员提供程序功能可能会错过哪些重大优势?

【问题讨论】:

【参考方案1】:

滚动您自己的身份验证系统绝不是个好主意。有很多方法可以弄错,在测试中仍然似乎起作用,直到一年后你发现你的网站在六个月前被破解。

始终尽可能依赖您的平台为您提供的安全代码,无论是 asp.net 还是其他任何平台。这样做,系统就会得到具有更多部署的供应商的支持,因此可以更轻松地发现和修复错误,即使您确实有问题,当您的老板询问时,您也可以将责任归咎于供应商。更不用说,一旦您第一次使用供应商的解决方案,额外的部署将会更快。这是正确的做法。

ASP.Net Membership 提供程序远非完美,但我向您保证,它比从头开始构建它更可取。

【讨论】:

虽然我基本同意,但基本的 ASP.NET 成员资格提供程序包含一大堆不一定需要的东西。如果我想要一个干净的系统,我可能会推出自己的系统,只使用我需要的那几种方法,而不是使用标准的方法。对此有何想法? 通常使用提供者模型,您只实现您想要使用的方法和属性。这些类是抽象的,因此当您实现时,您必须“定义”(覆盖)继承的抽象成员,但通常的做法是在您不想使用的那些成员中添加一个简单的 throw NotImplementedException。如果您不打算使用每个方法,请务必不要实际实现每个方法的代码。 当然,但是如果您自己实现所有必需的东西,为什么不只使用所需的方法创建一个自定义类呢?基类是否为您提供了您自己无法轻松获得的东西? @Arve - 是的,确实如此。仅仅因为它是一个抽象类,并不意味着任何地方都没有代码。它只是意味着有一些你必须实现的抽象方法。还有其他非抽象的方法,以及框架中的其他地方知道如何以正确的方式挂钩到 stock 类。 滚动你自己的系统是个坏主意。 @Arve 在上面的答案中womp 很好地记录了提供商的要点和优势。由于未使用的成员,无疑会有更多的代码,但是与获得的优势相比,这确实是一个小问题。拥有最少的代码并不总是最好的解决方案。 走你自己的路不会为了节省一点代码而胜过内置的可插拔功能。【参考方案2】:

provider model are outlined here 的优点,简而言之:

    某些开箱即用的 Web 控件是为使用成员资格提供程序模型而构建的,例如 Login control/view 和创建用户向导。因此,您错过了无需编写任何代码即可为所有页面创建登录仪表板的 1 步配置。

    只需在 web.config 文件中进行简单更改即可交换提供程序。并不是说您不能编写自己的登录内容来做同样的事情,但是您可以在以后的某个时候轻松编写自定义提供程序并将其切换到您的应用程序中,而无需更改应用程序中的任何内容。

    李>

    提供了所有基础知识。默认会员提供者具有密码检索、帐户锁定、多种密码加密方法、有效密码限制规则配置和用户管理,所有这些都是开箱即用的。对于大多数从头开始 ASP.Net 应用程序的人来说,仅使用它就可以大大减少设置时间。

    您的应用程序的一个大组件已经过审查。您无需担心调试所有自己的身份验证代码!这意味着当出现错误时,您通常会在站点中断之前得到修复,如果没有,您也有能力推卸责任。

【讨论】:

这些答案中的大多数不是不使用您自己的会员服务提供商的原因。正确实施后,您仍然会得到这些东西:) 这个论点几乎可以应用于任何事情。他确实特别要求优势。 ++ 他说了什么。除非您现在和将来有真正令人信服的理由来浪费您的时间,否则利用现有的框架代码通常是最佳途径。【参考方案3】:

我同意Ayende's feelings about this:

它是一个巨大的 API,它做出了很多假设,并且就它给你的东西和你必须实现的东西而言,使用它真的不好

这也是我的经验。每当我实现了自己的会员提供程序(在撰写本文时两次)时,我都没有实现绝大多数被覆盖的方法,因为我永远不会调用它们并且我没有使用任何网络表单使用它们的控件。

如果 Sql 和 Active Directory 提供程序能满足您的所有需求,它们就很棒。但如果他们不这样做并且您正在考虑实施提供程序,那么您可能会有更好的方法。

不要将 MembershipProvider 与 FormsAuthentication 混淆,我的应用程序仍然经常依赖它。这是负责将用户的身份验证令牌包装在 cookie 中并在客户端和服务器之间传递的机制。据我所知,FormsAuthentication 没有任何问题,我不建议重新发明它。

如果您不想实现几十个MembershipProvider methods、RoleProviderMethods 和ProfileProvider methods,那么只需实现IPrincipal 和IIdentity,然后做您需要做的事情。 Here's an example 让这 2 个接口与 FormsAuthentication 一起工作,这很简单。

另外,请注意,您需要明智地存储用户的凭据。 SqlMembershipProvider does 至少可以存储散列加盐密码。确保你至少也这样做。 Here's a nice piece of code 帮助解决这个问题。通知the slow hashing algorithm used。不要吸毒。

更新 (2013-12-16)

自从我写这篇文章以来,ASP.net 中的情况发生了变化。 ASP.NET Identity 替换了之前的会员功能。

我的建议是使用新的东西,因为:

您可以实现各种接口来组成满足您需求的解决方案。这意味着您可以实现自己想要的部分,而忽略不需要的部分。 您可以完全更改身份数据的存储位置/方式,同时保留控制密码散列方式的默认实现。 OAuth 和 OpenID 功能。 您可以在任何基于 OWIN 构建的框架中使用相同的系统。

API 比以前稍微复杂一些,但更灵活。

【讨论】:

感谢您更新您的答案,以便随着技术的发展保持相关性和现代性。【参考方案4】:

如果您的解决方案运行良好,请坚持下去。 “如果某事有效,请不要修复它”等等。否则,考虑到 Membership API 背后的程序员小时数、QA 小时数和用户小时数是您自己想出的任何东西的数千倍。

【讨论】:

没错。很多人很难意识到他们自己开发的解决方案是一团糟。这就像承认你的孩子很丑一样。 你的孩子可能很丑,但我的孩子很漂亮。 :p【参考方案5】:

您可能会从这些其他热门问题中获得一些见解:

Which authentication and authorization schemes are you using - and why?

Microsoft Membership Provider Vs Custom Provider Vs Complete Custom Login System

Anyone uses ASP .NET Membership?

Alternatives to .Net Membership

【讨论】:

【参考方案6】:

会员资格不仅仅是会员资格(登录名、电子邮件、密码和相关功能)。 Aspnet 将成员资格与个人资料分开,并且可以将它们整合在一起。个人资料就是您所说的“额外字段”。 即使您没有会员资格,您也可以拥有带有一些自定义功能的匿名个人资料。例如,用户可以设置首选项、返回站点并仍然拥有它们,但仍然不注册。然后,当您注册时,可以迁移匿名个人资料并将其与您的新会员资格相关联。

当你跳过它时,你基本上会错过它。

此外,如果您选择使用内置或第三方控件来利用会员资格和个人资料,您也会错过它。

您可以实现一个提供者,而不是一次性删除提供者模型。

【讨论】:

【参考方案7】:

在您的情况下,经过身份验证的用户是例外,而不是常态,因此推出您自己的用户可能没有什么坏处。

.net 提供的一件事是暴力攻击预防,如果有人试图暴力破解管理员密码,管理员帐户将被锁定。

【讨论】:

【参考方案8】:

我对内置 ASP.Net 身份验证的复杂性感到痛苦。我厌倦了必须为我永远不会使用的功能编写代码。 (以及留下一堆 NotImplemented 函数)。我也厌倦了使用 GUID 以外的东西和在每个页面加载时有多个数据库往返(仅用于身份验证)的困难......所以,我推出了自己的。它被命名为FSCAuth,并获得了 BSD 许可。

我也让它比 ASP.Net 的内置身份验证更难出错。所有 cookie 处理和实际哈希都留给 FSCAuth 的核心,而您只需担心将用户存储在数据库中并控制需要在哪些页面上进行身份验证。

如果您面临 ASP.Net 的内置身份验证问题并自行开发,我建议您先看看我的身份验证库,如果不只是将其用作起点。

【讨论】:

【参考方案9】:

您如何保存用户的密码?如果您以纯文本格式保存,这是一个重大风险。 ASP.NET Membership 系统的一个优点是它通过散列加密密码,开箱即用。

【讨论】:

以上是关于*不*使用 asp.net 会员提供程序是个坏主意吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在高流量网站中使用 Session 存储状态是个坏主意?

为 facebook 开发一个 .net 自定义会员提供程序

为啥注入 javascript 代码是个坏主意

ASP.NET MVC 和 ASP.NET 成员资格模板提供程序

在 WCF 服务中使用 ASP.NET 成员资格提供程序身份验证

在VS2010 ASP.NET开发服务器上运行新的MVC3解决方案;会员数据库在哪里?