Resetting Password with ASP.NET 2.0 Membership and Multiple Providers

If you ever have wanted to be able to programmatically change (reset) a users  password while at the same time continuing to be able to use the question and answer feature, this post is for you.  The problem is that if you use code like this:

 string username = "user";
 string password = "pass@word";
 MembershipUser mu = Membership.GetUser(username);
 mu.ChangePassword(mu.ResetPassword(), password);

You will find that if you have in your web.config requiresQuestionAnswer="true", you will get an error when you try and reset the password.  The elegant solution to this is to create an additional membeship tag in your web.config and reference it when you change passwords.  That is, add another provider like this:

<membership defaultProvider="SqlMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
    <clear/>
    <add name="SqlMembershipProviderOther" type="SqlProviderOneShot.SqlMembershipProvider"
    requiresQuestionAndAnswer="false"
     connectionStringName="EmailEmailConnectionString" applicationName="EmailEmail"
    enablePasswordRetrieval="false" enablePasswordReset="true"
    requiresUniqueEmail="true" passwordFormat="Hashed"
    minRequiredNonalphanumericCharacters="0" writeExceptionsToEventLog="false"
    minRequiredPasswordLength="1" passwordStrengthRegularExpression=""
    passwordAttemptWindow="10" maxInvalidPasswordAttempts="8"/>
</providers>
</membership>

Then, when you change your password, reference it as follows:


string username = "user";
string password = "pass@word";
MembershipUser mu = Membership.Providers["SqlMembershipProviderOther"].GetUser(username);
mu.ChangePassword(mu.ResetPassword(), password);

Hope this helps! At some point, I will integrate this functionality into my ObjectDataSource article that lets you display your membership information with a gridview or detailsview.

About Peter Kellner

Follow me:


Comments

  1. Dim UserName As String = Users.GetUserNameWithEmail(TextBox1.Text)
    Dim u As MembershipUser = Membership.GetUser(UserName)
    Dim newpassword As String = RandomNumber(234561, 10000000)
    u.ChangePassword(u.ResetPassword(), newpassword)
    If UserName.Length > 1 Then
    DAL.emails.NewMail(“yoursite.com change password”, “dear user new password :” & newpassword & “user name :” & UserName, TextBox1.Text)
    Label2.Visible = True
    Else
    Label2.Visible = True
    Label2.Text = “No email.”

    End If

    Catch ex As Exception
    Label2.Visible = True
    Label2.Text = “No email .”

    End Try

    End Sub
    Public Function RandomNumber(ByVal MaxNumber As Integer, _
    Optional ByVal MinNumber As Integer = 0) As Integer

    ‘initialize random number generator
    Dim r As New Random(System.DateTime.Now.Millisecond)

    ‘if passed incorrect arguments, swap them
    ‘can also throw exception or return 0

    If MinNumber > MaxNumber Then
    Dim t As Integer = MinNumber
    MinNumber = MaxNumber
    MaxNumber = t
    End If

    Return r.Next(MinNumber, MaxNumber)

    End Function
    End Class

  2. Which site design service are you using? Hoping I can get my own web site’s layout appearing more like your lay out, my url is alright but, I have been laboring on it to get it appearing as usable as your design.

  3. The following time I read a weblog, I hope that it doesnt disappoint me as a lot as this one. I mean, I do know it was my choice to learn, however I truly thought youd have something attention-grabbing to say. All I hear is a bunch of whining about one thing that you may fix for those who werent too busy searching for attention.King Regards Bert

  4. Heyyyy fool!!!!!!!!!!!!!

  5. Avocat Bucuresti says:

    I believe this is a fast way to reset the passwords. However, for me it seems to be a little bit dangerous to work in this way with the database. There is no danger to destroy the database ?

  6. Is no danger to destroy the entire database with the users name ? I suggest you to perform a backup before you apply the reset of the passwords. This option is better for saving and resetting the passwords in good conditions. Thank you for the script and the code.

  7. Whats up everyone I’m Idella Urbain. I found a program to profit a fantastic sum extremely easily and very fast. Look at the report. This is the site http://www.yoursite.com I hope this helps someone. Idella Urbain Dardagnac984@yahoo.com

  8. Arnold Recalde says:

    Heck of a nice blog keep up the nice work fella

  9. Hello! Very nice website, thanks. =)

  10. Thanks this was a great help. Keep up the good work ;o)

  11. Todays fresh passes. 4/11-09, Barely Legal Pass! Link/Download (http://sharembit.com/386/bar-legal.zip.html)

  12. Aaron Payne says:

    Thank you!!!

    Saved me a lot of time!

  13. Thank you!!!!

    I wanted to continue to use the randomly generated password in our store site, so I went with this:

    U.ResetPassword();
    string newPassword = U.GetPassword();

    and then some code to send the email

    Thank you so much!! I was going nuts having to deal with users who couldn’t remember their anwer, so I wanted to eliminate the step altogether. I looked around anough to get really frustrated, and then … voila!!

  14. Simple, elegant, and although published 2 1/2 years ago, stills proves helpful today. This saved me so much time and frustration. Thank you for sharing it, Peter.

  15. Frederick says:

    Thanks for the hint!
    Here’s my solution that worked for me.

    http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_2.0/Q_24515442.html

  16. Laurie says:

    Thanks for the tip, Peter. This was extremely useful!

  17. Hi,

    Thanks for the advice on setting up the second membership provider to resolve this issue.

  18. Peter Kellner says:

    I should not have referenced a custom membership provider in my example. Better to have done something like:


    connectionStringName="MyLocalSQLServer"
    applicationName="MyAppName"
    type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

  19. Hi Peter,

    First, thanks for creating this solution, as I am sure it will work for me. Many thanks to you and others who provide examples of their work.

    I am having the same problem as Stephen:

    Parser Error Message: Could not load type ‘SqlProviderOneShot.SqlMembershipProvider’.

    Source Error:

    Line 19:
    Line 20:

    Do I need to create another complete custom MembershipProvider class? or ?

    Thanks again.

  20. After talking with Peter, and looking at his code again, it worked like a champ. The part that kind of threw me for a loop was using the reset function as the old password. Here is my code in VB. Keep in mind that my provider MembersAdmin is just for the admin section of the client’s site.

    Dim U As MembershipUser = Membership.Providers(“MembersAdmin”).GetUser(SUserName, False)
    If Not U Is Nothing Then
    U.ChangePassword(U.ResetPassword(), strPassword)
    txtPassword.Text = “”
    msgProgress.Text = “Password Changed”
    End If

  21. Atomiton

    I am in the same boat as Kenny. I have a client that needs to be able to change a password for their user. Sometimes it is like pulling teeth to get these guys to walk through the process. So I set it up as above, but in order to change the password, I need old and new. If i reset it, it will go to their email and it is lost. So I figure my choices are like this.

    1) change their email to the admins, fire the reset, get the new password. Then change their email back, use the emailed password to change the password to what they wanted.

    2) somehow reset the password and display it on the screen without actually mailing it. Follow the second half of #1 and change to what they wanted.

    3) Figure out how to hash the new password and store that result in the table with the salt key and bypass the provider. Just do a straight stored procedure.

    Any thought to point me in the right direction and maybe shoot holes in my thinking? The biggest thing I need to be able to set the password to a password of my choosing, through an admin account. Everything I can think of comes up messy.

  22. Kenny… not sure if you’re still reading this… but it’s probably better to just use the ResetPassword() method. It will email them their new password and you don’t have to worry about it. It’s more secure too.

    You will need to implement two membership profiles for this.

    I won’t go into details as there are lots of posts explaining it better than I do.

    However, if you’re looking at Adding an AdminProvider for the built-in SQL Express DB that is created when you enable security from the WAT while leaving the default one for users, this could be your Web.config:

    <membership defaultProvider=ACPMembershipProvider”>
    <providers>
    <clear/>
    <add name=”ACPMembershipProvider” type=”System.Web.Security.SqlMembershipProvider”
    connectionStringName=”ACPDevSQL”
    applicationName=”ACPPortal”
    minRequiredPasswordLength=”3″
    minRequiredNonalphanumericCharacters=”0″
    enablePasswordRetrieval=”true”
    passwordForma=”Encrypted”
    enablePasswordReset=”true”
    requiresQuestionAndAnswer=”true”
    requiresUniqueEmail=”false”/>
    <name=”ACPMembershipProviderAdmin” type=”System.Web.Security.SqlMembershipProvider”
    connectionStringName=”ACPDevSQL”
    applicationName=”ACPPortal”
    minRequiredPasswordLength=”3″
    minRequiredNonalphanumericCharacters=”0″
    enablePasswordRetrieval=”true”
    passwordForma=”Encrypted”
    enablePasswordReset=”true”
    requiresQuestionAndAnswer=”false”
    requiresUniqueEmail=”false”/>
    </providers></membership>

  23. Kenny… not sure if you’re still reading this… but it’s probably better to just use the ResetPassword() method. It will email them their new password and you don’t have to worry about it. It’s more secure too.

    You will need to implement two membership profiles for this.

    I won’t go into details as there are lots of posts explaining it better than I do.

    However, if you’re looking at Adding an AdminProvider for the built-in SQL Express DB that is created when you enable security from the WAT while leaving the default one for users, this could be your Web.config:

  24. Never mind the second question. I have extended the ChangePassword control to include the Question/Answer combination.

    The first question is still something I’de like to figure out though. Everything’s working the way I have it set up now but it’s kindof a bubble gum/scotch tape solution.

    Thanks

  25. I have a situation that I have two questions about.

    First, the situation:

    I have implemented a capability in our website where certain “power” users are able to add new website users to our database by uploading a spreadsheet. The spreadsheet contains the new user’s First and Last name and their e-mail; the e-mail becomes their login UserName.

    Upon spreadsheet upload, as records are added to a staging table in our database, I call dbo.aspnet_Membership_CreateUser passing it the parameter values it expects. right now, I am passing a known hashed password and salt value and a known password question and password answer value.

    As a separate process, I have a windows service that polls the database for newly-added users and calls Membership.Provider.ChangePassword to update their password to a unique temporary password and then send them an email with instructions how to log in with their email as the UserName and the temporary password we provide.

    These users, when they log into the website, are forced to change their temporary password with the ChagePassword control before they can do anything else.

    The first question is:

    How can I create a hashed version of the temporary password in T-SQL that is compatible with Membership/Roles and pass it to dbo.aspnet_Membership_CreateUser right from the onset instead of having to change it (again) in my windows process?

    The second and more urgent question is:

    Since new users added in this fashion never see the CreateUserWizard control and therefore never have an opportunity to enter their own password question/answer combination, what would be the best (and most secure) way for me to prompt them for a new password question/answer combination at the time I direct them to change their passowrd?

    Right now I have no “Forgot Password?” functionality because of this conundrum.

    Any guidance would be greatly appreciated…

  26. Hi Peter,
    I’ve setup my page so that I have 2 textbox, 1 for the username and the other for the new password that I want to set it to. Is there a way so that my setup will work? I’m the Admin and sometime the user want me to reset the password for them, either they forgot the password as well as the answer to the secret question, or something going on with their email.

    Thank you very, very much.
    Kenny.

  27. Administrator says:

    Kenny,
    You are right that GetUser() does not work. You can always get the currently logged in user by doing Context.User.Identity.Name.
    -Peter Kellner

  28. Hi Peter,
    Thank you very much for the article, this is what I’m looking for… However, I’ve received error in this code:

    Membership mu = Membership.Providers["CustomizedAdminMembershipProvider"].GetUser(Username);

    This is the error:
    No overload for mthod ‘GetUser’ takes ‘1’ arguments

    Any idea why?
    Thank you very much,
    Kenny.

  29. This is a great post. It worked great after passing in the IsUserOnline value with the user name. Thanks a lot.

  30. Stephen says:

    Hi Peter,

    Thanks for the article, as i believe it can solve my problem but when i do …

    …and…

    MembershipUser mu = Membership.Providers["SqlMembershipProviderOther"].GetUser(UserName, false);

    i get the following error.

    Configuration Error
    Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

    Parser Error Message: Could not load type ‘SqlProviderOneShot.SqlMembershipProvider’.

    Source Error:

    Line 19:
    Line 20:

  31. Polly,

    You’ll need two distinct membership providers to do this. The first provider (your default) would be used for all curcumstances EXCEPT changing passwords. The second provider would function identically to your first, except for the RequiresQuestionAndAnswer=”false” option. Use this provider only when changing (resetting) the password. That should do it.

    Thanks!

  32. Polly Woodhouse says:

    Hi Peter,
    Thank you very much for your article which is much appreciated.

    I defined a new Membership Provider in my config file anyway, as I needed to connect to a SQL 2005 db rather than the express version.

    I then set the RequiresQuestionAndAnswer to false as you mentioned and I was then able to change somebody else’s password.

    However, as the RequiresQuestionAndAnswer is now false, it means that the PasswordRecovery control does not ask a user for an answer to their security question, which is a big disadvantage. Also, when creating a new user, it does not ask for a security question either. Is there any way that I can all the sets of functionality to co-exist and somehow set the config file depending what I am trying to do.

    Thank you so much for your help.

    Kind regards,

    Polly

  33. Lionel Thomas says:

    Hi Peter,
    Thanks for the reply. I did look at this post but when I tried to reference the provider from the providers collection it gave me an error.

    MembershipUser mu = Membership.Providers["MembershipProvider" + strLocation].GetUser(strCurrentUser);

    CS1501: No overload for method ‘GetUser’ takes ‘1’ arguments

    If I add the second parameter it works fine.
    But in the case of the GetAllUsers when I add the 3 parameters(index,pagesize,totalrecords) it paginates the data. This of course changes the logic.

    MembershipUserCollection muc = Membership.Providers["MembershipProvider" + strLocation].GetAllUsers();

    CS1501: No overload for method ‘GetAllUsers’ takes ‘0’ arguments

    This raises 2 issues for me.
    1. How can I modify your wrapper classes to allow for the overriding of the provider or just change the logic for the different providers? I also want to use roles and profiles.
    2. How does one know this stuff in the first place? I have spent a lot of time studing the classes, methods etc. but there doesn’t seem to be any indication of what methods can be overriden. I am pretty new to microsft classes and wish that I was gaining confidence in their use without making a career out of it.

    Sorry for the venting!

    My main objective is to reuse all the pages in my site by just changing the database for each location. I don’t want a copy of my website for each location. The ability to readily select connection strings and providers at run time seems to be hard to do. Any articles or tutorials of this nature would be much appreciated.

    I thank the gods of the internet for people like you who share their knowledge so freely.

    Thanks and regards,
    Lionel

  34. Very interesting. I did have this problem mainly because the strong password (7+ chars 1 special char) regular expression seems to be invoked even though I had blanked out the passwordStrengthRegularExpression attribute (just as you have). I
    have a different solution to this problem in that I use the sp that’s provided i.e.

    Declare @UserName NVarChar(30)
    Declare @Password NVarChar(30)
    Declare @Application NVarChar(255)
    Declare @PasswordSalt NVarChar(128)

    set @UserName = ‘mclarke’
    set @Password = ‘password123′
    set @Application = ‘WebPartMiniHost’
    Set @PasswordSalt = (SELECT 1 PasswordSalt FROM aspnet_Membership WHERE UserID IN (SELECT UserID FROM aspnet_Users u, aspnet_Applications a WHERE u.UserName=@UserName and a.ApplicationName = @Application AND u.ApplicationId = a.ApplicationId))

    Exec dbo.aspnet_Membership_ResetPassword @Application, @UserName, @Password, 10, 10, @PasswordSalt, -5

Your Comments

*

Protected with IP Blacklist CloudIP Blacklist Cloud

Follow

Get every new post delivered to your Inbox

Join other followers: