ASP.NET 会员提供商 - 重置密码功能 - 电子邮件确认和密码更改

发布于 2024-09-07 03:38:09 字数 597 浏览 10 评论 0原文

有谁有以下功能的解决方案(示例代码):

  • 创建 randomGuid/Cryptographically 强随机数
  • 发送包含以下内容的唯一 URL 用户电子邮件的随机数 地址
  • 确认后,会询问用户 更改密码

我的提供程序当前以这种方式参数化:

enablePasswordRetrieval="false" 
enablePasswordReset="true" 
requiresQuestionAndAnswer="false" 
applicationName="/" 
requiresUniqueEmail="true" 
passwordFormat="Hashed" 
maxInvalidPasswordAttempts="5" 
minRequiredPasswordLength="5" 
minRequiredNonalphanumericCharacters="0" 
passwordAttemptWindow="10" 
passwordStrengthRegularExpression="" 
name="AspNetSqlMembershipProvider"

已讨论此类过程的安全问题

Does anyone have a solution (sample code) for the following features:

  • Create a randomGuid/Cryptographically
    strong random number
  • Send a unique URL containing the
    random number to the user's email
    address
  • When confirmed, the user is asked
    to change password

My provider is currently parametrized this way:

enablePasswordRetrieval="false" 
enablePasswordReset="true" 
requiresQuestionAndAnswer="false" 
applicationName="/" 
requiresUniqueEmail="true" 
passwordFormat="Hashed" 
maxInvalidPasswordAttempts="5" 
minRequiredPasswordLength="5" 
minRequiredNonalphanumericCharacters="0" 
passwordAttemptWindow="10" 
passwordStrengthRegularExpression="" 
name="AspNetSqlMembershipProvider"

The security issues with this type of procedure have been discussed here before.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只等公子 2024-09-14 03:38:09

Rui,几个月前我也遇到过类似的情况,之前没有接触过会员提供商,我很难正确实施它,因为我认为你必须按原样实施和使用整个事情,或者什么也没有。

好吧,我很快发现你只能使用它的一部分,而不是整个对象。例如,在我的应用程序中,我有自己的用户对象以及自己的密码和登录模块,但我需要使表单身份验证正常工作。所以我基本上只使用会员资格提供程序来完成该部分。我不会重写任何方法或任何内容,只是将其用于 FormsAuthentication,然后使用我自己的存储库来更改密码、验证用户名密码等。

这是我在 MVC 中的登录代码的片段。

   var authTicket =  new FormsAuthenticationTicket(1, user.UniqueName, DateTime.UtcNow, DateTime.UtcNow.AddHours(2), rememberMe, cookieValues);
    var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { Expires = DateTime.UtcNow.AddDays(14) };

    httpResponseBase.Cookies.Add(authCookie);

这使我能够使用 FormsAuthentication.SignOut();方法和会员资格提供商提供的其他方法。

关于你的问题,重新创建一个 randomGuid/Cryptologically 强随机数,这是一个你可以使用的好方法,我不久前发现了它,很抱歉,但不记得在网络上的哪里

/// <summary>
/// A simple class which can be used to generate "unguessable" verifier values.
/// </summary>
public class UnguessableGenerator
{
    const string AllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/^()";
    const string SimpleAllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /// <summary>
    /// Generates an unguessable string sequence of a certain length
    /// </summary>
    /// <param name="length">The length.</param>
    /// <param name="useSimpleCharacterSet">if set to <c>true</c> [use simple character set].</param>
    /// <returns></returns>
    public static string GenerateUnguessable(int length, bool useSimpleCharacterSet = false, string additionalCharacters = "")
    {
        var random = new Random();

        var chars = new char[length];

        var charsToUse = useSimpleCharacterSet ? SimpleAllowableCharacters : AllowableCharacters;
        charsToUse = string.Format("{0}{1}", charsToUse, additionalCharacters);

        var allowableLength = charsToUse.Length;

        for (var i = 0; i < length; i++)
        {
            chars[i] = charsToUse[random.Next(allowableLength)];
        }

        return new string(chars);
    }




    /// <summary>
    /// Generates an ungessable string, defaults the length to what google uses (24 characters)
    /// </summary>
    /// <returns></returns>
    public static string GenerateUnguessable()
    {
        return GenerateUnguessable(24);
    }
}

发送包含随机数的唯一 URL数字到用户的电子邮件地址,您需要的是在您的用户表或任何表中存储随机 ID,然后在用户可以用来验证的电子邮件中精心设计的 URL 中使用它。

这将要求您创建一个接受该类型 Url 的 Url,然后您必须从查询字符串中提取所需的部分并更新您的用户对象。

对于“确认后,要求用户更改密码”,默认情况下,表中有一个位标志强制用户更改密码,如果您需要强制用户更改密码,这也会在以后派上用场。因此,您的登录代码会查看该位标志是否打开,如果是,它将首先强制更改密码。然后,一旦用户更改了密码,您将关闭此标志。

希望这有帮助。

Rui, I was in a similar boat a few moths ago, and not having had a great deal of exposure to the membership provider before, I struggled to get it implemented properly, because I thought you have to implement and use the whole thing as is, or nothing at all.

Well I soon discovered that you can only use parts of it, not the entire object. For example in my application I have my own user object and my own password and login modules, but I needed to get forms authentication working. So I basically just use the Membership provider for that part. I am not overriding any methods or anything, just use it for FormsAuthentication, then I use my own repositories to changing passwords, verifying username passwords etc.

Here is a snippet from my login code in MVC.

   var authTicket =  new FormsAuthenticationTicket(1, user.UniqueName, DateTime.UtcNow, DateTime.UtcNow.AddHours(2), rememberMe, cookieValues);
    var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { Expires = DateTime.UtcNow.AddDays(14) };

    httpResponseBase.Cookies.Add(authCookie);

This enables me to use the FormsAuthentication.SignOut(); methods and other methods the membership provider makes available.

On your question re Create a randomGuid/Cryptographically strong random number, here is a good method you can use, I found it a while ago, and I am sorry but can't remember where on the web

/// <summary>
/// A simple class which can be used to generate "unguessable" verifier values.
/// </summary>
public class UnguessableGenerator
{
    const string AllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/^()";
    const string SimpleAllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /// <summary>
    /// Generates an unguessable string sequence of a certain length
    /// </summary>
    /// <param name="length">The length.</param>
    /// <param name="useSimpleCharacterSet">if set to <c>true</c> [use simple character set].</param>
    /// <returns></returns>
    public static string GenerateUnguessable(int length, bool useSimpleCharacterSet = false, string additionalCharacters = "")
    {
        var random = new Random();

        var chars = new char[length];

        var charsToUse = useSimpleCharacterSet ? SimpleAllowableCharacters : AllowableCharacters;
        charsToUse = string.Format("{0}{1}", charsToUse, additionalCharacters);

        var allowableLength = charsToUse.Length;

        for (var i = 0; i < length; i++)
        {
            chars[i] = charsToUse[random.Next(allowableLength)];
        }

        return new string(chars);
    }




    /// <summary>
    /// Generates an ungessable string, defaults the length to what google uses (24 characters)
    /// </summary>
    /// <returns></returns>
    public static string GenerateUnguessable()
    {
        return GenerateUnguessable(24);
    }
}

For Send a unique URL containing the random number to the user's email address, what you need is in your User table or any table a way to store a random id and then use that in a crafted url in an email that the user can use to verify.

This will require you to create a Url that will accept that type of Url, and then you have to extract the parts you need form the querystring and update your user object.

For When confirmed, the user is asked to change password, by default have a bit flag in your table that forces a user to change his password, this will come in handy later too if you need to force a user to change password. So then your login code looks to see if this bit flag is on, and if so, it will force a password change first. Then once the user has changed his password, you will turn this flag off.

Hope this helps.

归属感 2024-09-14 03:38:09

至少使用 Guid 类作为 guid。
您也许可以自定义结果

var guid = Guid.NewGuid();

......
要发送链接

var msg = new MailMessage();
msg.From = new MailAddress("YOUR_ADDRESS");
msg.To.Add(new MailAddress("CLIENT_ADDRESS"));
msg.Subject = "YOUR SUBJECT";
msg.Body = @" SOME TXT.... http:\\resetPassword.aspx?guid=" + guid;
var smtpClient = new SmtpClient("SMTP_SERVER", 9990);
smtpClient.Send(msg);

......

您只需要创建一个像resetPassword.aspx这样的网页并在页面中处理加载参数“guid”,它应该链接到数据库中的用户

At least use the Guid class for the guid.
You may be able to customize the result

var guid = Guid.NewGuid();

.....
To send the link

var msg = new MailMessage();
msg.From = new MailAddress("YOUR_ADDRESS");
msg.To.Add(new MailAddress("CLIENT_ADDRESS"));
msg.Subject = "YOUR SUBJECT";
msg.Body = @" SOME TXT.... http:\\resetPassword.aspx?guid=" + guid;
var smtpClient = new SmtpClient("SMTP_SERVER", 9990);
smtpClient.Send(msg);

.....

After you only have to do a web page like resetPassword.aspx and handle in the page load the parameters "guid" which it should be link to the user in the dataBase

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文