views:

2535

answers:

4

I've had to create a custom membership provider for my current ASP .Net project in order to fit in with our database schema, and am having problems configuring it to lockout a user if they get their password wrong three times, as is supported by the standard providers.

Is this something I need to implement myself, or should it be supported inherently?

I have no code that specifically deals with it (and none of the interface members seem to deal with it specifically), but if I need to implement it myself, how do I go about informing the user they are locked out? Do I need to raise some sort of exception in ValidateUser?

Solution

Shame I can't mark two answers, the links provided by Dave R give a great in depth look at how membership works, and what Zhaph pointed out was just what I ended up doing, handling the locked out logic in the custom membership provider.

I then handled the error condition by using the Login control's LoginError event and checked in there to see if the user was locked out in order to show the appropriate error message.

A: 

In your custom membership provider, you should implement the ValidateUser function. There you not only check if the username and password are valid, but you also retrieve the number of invalid password attempts etc from your datastore. If the username/password is valid, reset the password attempt count, otherelse increase the attempt count. The SqlMembershipProvider also stores the LastAttempt datetime, so you cannot bruteforce you way in because you are not allowed to attempt within a certain time frame.

Michiel
+2  A: 

Scott Mitchell has written an excellent series of tutorials on the ASP.NET site. This link includes information on creating a custom provider and discusses the locking logic:

http://www.asp.net/LEARN/security/tutorial-06-cs.aspx

There's also no in-built method to unlock accounts (i.e. you have to do this through database tools if you're using something similar to the SqlMembershipProvider). Scott has also written an article about creating a UI to manage this, which you can find here:

http://www.asp.net/LEARN/security/tutorial-14-vb.aspx

I actually recommend reading the whole series. Scott's an excellent communicator.

I hope this helps.

Dave R.
A: 

This is something that you'd have to write yourself.

The default database schema has the following columns in the aspnet_Membership table:

IsLockedOut
FailedPasswordAttemptCount
FailedPasswordAttemptWindowStart

The attempt count will be incremented on every failed attempt within the attempt window, and the time of the first failed attempt is stored in the window start column, once FailedPasswordAttemptCount equals the maxInvalidPasswordAttempts from the configuration, the IsLockedOut is set.

As Michiel states, your ValidateUser method will then need to check these values based on the settings in the provider configuration - by default these are:

maxInvalidPasswordAttempts="5"
passwordAttemptWindow="10"

Once the user has had the maximum login attempts, you'll need to ensure that you have set the MembershipUser.IsLockedOut is set from your provider - you can then check that value and behave appropriately - if you are using the default Login controls, this value will probably already be checked for you.

Zhaph - Ben Duguid
A: 

Replicate the conditions that lead to lockout (too many bad login attempts). Because Membership providers make a trip to their backend every time, it is sensible to limit this approach to providers with reasonable number of MaxInvalidPasswordAttempts.

if (0 < Membership.MaxInvalidPasswordAttempts && Membership.MaxInvalidPasswordAttempts < 100)
       {
                for(int i = 0; i <= Membership.MaxInvalidPasswordAttempts; i++)
                {
                    Membership.ValidateUser(userName, "jfdlsjflksjlkfjsdlkfjsdl");
                }
        }
Samo Fabčič