How does Membership.ValidateUser method access a database? - c#

I wanted to build a membership system at the beginning of my MVC project and I used Membership.ValidateUser method to verify credentials. However I could not understand how does this method access my database and check my email and password informations.
[HttpPost]
[ActionName("Login")]
public ActionResult Login(LoginModel loginModel)
{
if (Membership.ValidateUser(loginModel.Email, loginModel.Password))
{
FormsAuthentication.SetAuthCookie(loginModel.Email, true);
return Json(true);
}
return new JsonNetResult()
{ Data = new { Error = true, Messages = new[] { new { Message = "Wrong username or password" } } } };
}

It' used the MembershipProvider specified on your Web.config file to validate the user. By default, it uses DefaultMembershipProvider

Membership.ValidateUser method at first check membership defaultProvider in your web.config file which matches with name that you provide like below:
<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
connectionStringName="Context" applicationName="myapp"
enablePasswordRetrieval="false" enablePasswordReset="true"
requiresQuestionAndAnswer="false" requiresUniqueEmail="true"
passwordFormat="Hashed" minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="0" />
</providers>
</membership>
Above configuration will call .net framework abstraction class MembershipProvider -> ValidateUser (abstract method) which implementation lies in SqlMembershipProvider -> ValidateUser method that you have configured in your web.config file [like above].In that method it simply call two store procedures of your database , first one is aspnet_Membership_GetPasswordWithFormat which check your application name, username , last login activity date and current time and based on that makes you authenticate and secondly call to other store procedure which name is aspnet_Membership_UpdateUserInfo which is self explanatory as you realize which update aspnet_membership table with columns like islockedout, lastlockoutdate, failedpasswordattemptcount.. etc.
Hope this helps you.

Related

Integrating SimpleMembershipProvider in ASP.NET MVC Application

I'm having a hard time implementing (or integrating) ASP.NET SimpleMembershipProvider. I already have the database tables from a previous version of the application and I don't want to create new user tables, roles, etc... I want to use the existing tables (already mapped with entity framework) so the users in the database can log in to the future application. Here's what I did:
Web.config
<authentication mode="Forms">
<forms loginUrl="~/Auth" timeout="2880" />
</authentication>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear />
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>
<roleManager enabled="true" />
Global.asax
WebSecurity.InitializeDatabaseConnection("MyConnectionString", "tblCreds", "IdCred", "Login", false);
// I put false in the end because I don't want it to create new tables
Controller:
[HttpPost]
public ActionResult Index(UserCreds creds)
{
if (ModelState.IsValid)
{
UserBLL bll = new UserBLL();
BaseUser authUser = bll.Authenticate(creds.Login, creds.Password);
if (authUser != null)
{
WebSecurity.Login(creds.Login, creds.Password);
return RedirectToAction("Index", "Home");
}
}
ViewBag.ErrorMessage = "Error";
return View();
}
And I'm getting this exception:
System.Data.SqlClient.SqlException: Invalid object name 'webpages_Membership'
Thanks you for your help :)
You are seeing that exception as SimpleMembershipProvider internally uses these table names. Unfortunately they are not overridable (until last i used it).
The design goal with SMP was to provide an out of the box working model of membership with its own table schema. You can configure user table name and add more column but not everything.
See this question for more information.

Webmatrix Reset password

I want to know how to set a password using mvc4 providers without knowing the old password ?
I want to make a forgot password function, where the user receives a secure link via email and then clicks the link, gets directed to the my application and then has to fill in only the new password, no security questions needed.
It was easy to do this with the membership providers that came with mvc3. I'm now using the simple membership providers that come with mvc4 and I'm having trouble getting it working.
the code so far looks as simple as:
MembershipUser user = Membership.GetUser( cust.Email );
String pass = user.GetPassword();
Boolean success = WebSecurity.ChangePassword( cust.Email, pass, model.Password );
It currently gives error on the above line that calls GetPassword() with the error :
Specified method is not supported.
I'll show the relevant section in the web.config also here :
<system.web>
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear/>
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
</providers>
</roleManager>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear/>
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"
enablePasswordRetrieval="true" enablePasswordReset="true" passwordFormat="Encrypted" requiresQuestionAndAnswer="false"
requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="5" minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10" />
</providers>
</membership>
Above I tried to add the attributes you use for the providers in mvc3 but it doesn't seem to be applicable here.
WebSecurity.GeneratePasswordResetToken generates and returns a unique string.
WebSecurity.ResetPassword uses that token to change the password.
Give the user a link to an action with the token as a parameter, then give them a simple form to change their password.

Debugging ASP.NET MVC3 custom membership provider

I'm trying to test my asp.net mvc3 custom membership provider. I can't seem to be able to step into any of the code - all I want to do for now is validate that the user is logged in.
What I've done so far is:
Implement the abstact MembershipProvider class:
public class SSDSMembershipProvider : MembershipProvider
{
public override bool ValidateUser(string username, string password)
{
return true;
}
Modify the web.config to use my new provider:
<membership defaultProvider="SSDSMembershipProvider">
<providers>
<clear/>
<add name="SSDSMembershipProvider" type="MvcApplication6.Infrastructure.SSDSMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
Added the Authorize attribute to the about HomeController:
[Authorize]
public ActionResult About()
{
return View();
}
Does the authorize attribute result in the ValidateUser method being called? If I put a breakpoint on ValidateUser it doesn't step in there and the browser goes straight to the logon page. Have I taken the right approach here?
did you change the code in your AccountController?
you have to change the code in the Method "LogOn" from Mebership.ValidateUser to a new instance of your SSDSMembershipProvider-Class and then call dthe ValidateUser method.
Authorize just redirects the user to login page, validate user shall be called once the user puts in his/her credentials and submit the login form.

MembershipService not initialized

following some example from Microsoft I created my custom MembershipProvider in my MVC application as
if (MembershipService == null) { MembershipService = new AccountMembershipService(new FcMembershipProvider()); }
and the web.config is configured as
<membership defaultProvider="FcMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add
name="FcMembershipProvider"
type="Fc.Web.WebAppMVC.Models.FcMembershipProvider"
connectionStringName="ApplicationServices"
enablePasswordRetrieval="true"
enablePasswordReset="true"
applicationName="FcWebMVC"
requiresQuestionAndAnswer="true"
writeExceptionsToEventLog="false" />
</providers>
</membership>
Problem is the Initialize method is not automatically called. any hint?
Thx
I think you need to get hold of your membership provider using the static Membership.Provider like so:
if (MembershipService == null) { MembershipService = new AccountMembershipService((FcMembershipProvider)Membership.Provider); }
(I put a cast in there which you may not need depending on what AccoundMembershipService is expecting.) This way ASP .NET's membership system should initialize it for you.
what is the class that implements "MembershipProvider" class ? beacause in your config file it's "FcMembershipProvider" and in the code it's AccountMembershipService.
I created a custom membership provider, I only implemented the "MembershipProvider" class, and added the config like you've done, I think you dont have to add code.

Change Password Issue in AspNet MembershipProvider

I am using AspNet Membership Provider in MVC 3.
I am facing issue in change password.
I have two functionality in my project
Forgot password : ask security question and based on security answer change password.
Admin change password: a admin can change password of any user without knowing old password or security answer.
Now the issue is that for functionality # 1, i have to make changes in web config for making requiresQuestionAndAnswer="true" for change password so that i can change password only if security answer is valid.
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
and i am using below code for changing password in forgot password:
string resetPassword = res.ResetPassword(model.PasswordAnswer);
MembershipService.ChangePassword(model.Username, newPassword, model.NewPassword)
now for situation # 2, where for admin i wants facility to change password of any user without knowing old password or security answer. which is only possible (as i know) by making requiresQuestionAndAnswer="false" .
Note:I am using separate MVC AREA for admin part, so may be a another web config can do some magic.
please suggest how can i have have both the features (reset password with security answer and without security answer) together in single application.
Thanks a lot
Finally got the answer:
In web config i set the requiresQuestionAndAnswer="true" so this resolves the issue#1, now for forgot password a security answer is required.
and for issue#2 where i want the facility for admin to change password of any user without knowing old password or security answer. I have used Reflection for it to change the value of private variable _RequiresQuestionAndAnswer to false then reset the password and then again set its value to true:
var _requiresQA = Membership.Provider.GetType().GetField("_RequiresQuestionAndAnswer",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
//change the value in the private field
_requiresQA.SetValue(Membership.Provider, false);
//do the reset
tempPassword = user.ResetPassword();
//set it's original value
_requiresQA.SetValue(Membership.Provider, true);
I got this solution at : http://djsolid.net/blog/asp.net-membership---change-password-without-asking-the-old-with-question-and-answer

Categories