我正在使用DefaultMembershipProvider开发一个C#ASP.MVC 4项目,我正在尝试用一种用户友好的方式来恢复/重置丢失的密码。
我的第一次尝试是让用户提供他们的用户名(这是一个有效的电子邮件地址),然后应用程序会生成随机密码(符合我们的要求),然后将密码通过电子邮件发送给用户。
我理想的解决方案是当用户点击忘记密码按钮时。系统会询问他们的用户名,这些用户名在提供时会导致电子邮件与URL一起发送(此URL也会附加到期日期)。此解决方案还会重置应用程序内的用户密码(在发送电子邮件之前)。当用户单击URL时,它们会自动登录并发送到更改密码表单。这个解决方案有问题吗?
对于配置,我设置了以下值:
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<clear />
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
答案 0 :(得分:6)
首先,这里有两个必须阅读[我再说一遍,必读]:
话虽如此,OWASP有一些关于如何实施身份验证的指南,您可以开始使用Authentication Cheat Sheet,针对您的特定情况Forgot Password Cheat Sheet。这也可以说是必读的。如果你不打算关注OWASP,我希望这是因为你决定,而不是因为你不知道更好。
无论如何,最好的摘要是后面的图像(取自上面的第一个链接),如果你只想记住一件事,就这样吧:
答案 1 :(得分:2)
您的方法存在缺陷 - 您写道发送电子邮件会重置用户密码。假设滥用者知道登录信息,这很容易被任何人重置为任何用户重置密码。换句话说,我只是坐在你的系统前面,只需点击“我不记得我的密码”并提供他们的用户名就可以阻止其他用户的帐户。
所以,你不必重置任何东西。该方法将为解锁请求(可以是数据库中的表)创建存储,其中每个请求由guid识别并具有到期日期,用户名和标记是否已使用请求的标记。当您发送电子邮件时,您在此请求存储中创建一条记录,并且该电子邮件包含指向guid的链接(请注意,解锁电子邮件中不需要其他信息)。
然后,当有人点击他们的电子邮件中的链接时,在服务器端您就有了请求的指示。从您的请求存储区中,您可以读取过期日期,用户名和信息(如果之前已使用过该链接)。然后,您将提供一个用户提供新密码的表单。
与您的方法相比,这样做的好处是不会干扰现有密码。此外,隐藏服务器端的所有信息并仅向用户公开guid的优点是不会向客户端暴露潜在的敏感信息(如链接到期日期)。