February 15th, 2007Resetting 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.









February 16th, 2007 at 7:11 am
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
February 20th, 2007 at 5:46 am
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
February 27th, 2007 at 9:53 am
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
May 14th, 2007 at 8:50 pm
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!
June 13th, 2007 at 2:47 am
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:
August 11th, 2007 at 4:06 pm
This is a great post. It worked great after passing in the IsUserOnline value with the user name. Thanks a lot.
August 14th, 2007 at 5:48 pm
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.
August 14th, 2007 at 6:10 pm
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
August 14th, 2007 at 6:18 pm
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.
October 29th, 2007 at 10:35 am
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…
November 1st, 2007 at 9:37 am
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
February 3rd, 2008 at 2:06 pm
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:
February 3rd, 2008 at 2:09 pm
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>
May 10th, 2008 at 7:49 pm
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.
May 10th, 2008 at 9:35 pm
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
June 17th, 2008 at 6:13 am
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.
June 17th, 2008 at 8:41 am
I should not have referenced a custom membership provider in my example. Better to have done something like:
applicationName="MyAppName"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
September 29th, 2008 at 6:54 am
Hi,
Thanks for the advice on setting up the second membership provider to resolve this issue.
May 8th, 2009 at 8:31 am
Thanks for the tip, Peter. This was extremely useful!
June 23rd, 2009 at 11:08 am
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
July 10th, 2009 at 8:22 pm
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.
August 4th, 2009 at 10:29 pm
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!!
August 19th, 2009 at 2:57 pm
Thank you!!!
Saved me a lot of time!
November 4th, 2009 at 6:33 am
Todays fresh passes. 4/11-09, Barely Legal Pass! Link/Download (http://sharembit.com/386/bar-legal.zip.html)
September 16th, 2010 at 9:10 am
Thanks this was a great help. Keep up the good work ;o)
October 6th, 2010 at 12:16 pm
Hello! Very nice website, thanks. =)
October 24th, 2010 at 4:47 pm
Heck of a nice blog keep up the nice work fella
October 25th, 2010 at 1:56 am
http://miserrors.blogspot.com/2010/10/aspnet-password-membership-change.html
November 21st, 2010 at 12:49 am
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
March 7th, 2011 at 5:24 am
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.
March 12th, 2011 at 3:55 am
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 ?
July 18th, 2011 at 1:27 pm
Heyyyy fool!!!!!!!!!!!!!
September 1st, 2011 at 5:39 am
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
September 9th, 2011 at 2:54 am
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.