share
Stack OverflowAdding 2FA to .NET web app using ASP.NET Membership
[+4] [2] Kevin Cress
[2018-07-25 04:24:41]
[ asp.net authentication webforms asp.net-membership two-factor-authentication ]
[ https://stackoverflow.com/questions/51510757/adding-2fa-to-net-web-app-using-asp-net-membership ]

Can anyone point me towards any tutorials for implementing two factor authentication using the old .NET Membership system?

I have a legacy web forms application that I'd like to add 2FA to, but all of the tutorials I find are for inplementing it in the newer ASP.NET Identity system.

Upgrading from the Membership system to the Identity system is not an option right now, unfortunately.

By asp membership do you mean the good ol' fashioned SQL membership provider for .net? - Phillip Morton
@PhillipMorton yes! - Kevin Cress
Did you get anywhere with this? I have had a look at the answer and it seems good but it would be interesting to know if it worked. The answer is not yet accepted. - Eval Knievel
I did not! I never got a chance to try the suggested answer. If you try it, can you let us know if it works? - Kevin Cress
[+1] [2021-09-06 10:24:00] Owen Smith

The custom membership provider described above is definitely useful but the implementation of 2FA that I used was https://github.com/RobThree/TwoFactorAuth.Net This comes as a nuget package [1] and is really well done!

[1] https://www.nuget.org/packages/TwoFactorAuth.Net/

1
[0] [2019-01-03 16:45:54] James Westgate

You will need to write a custom membership provider and find a way of passing multiple credentials to the MembershipProvider, either as an extra parameter or using a new method. Since the MembershipProvider is only created once per app domain, and could process multiple user requests, it is best not to split calls between authenticating the password and the 2nd factor.

The solution I came up with implements an additional interface and the provider is checked for this support when validating the credentials passed back to the server.

First, define an interface that accepts multiple factors (such as a password and OTP)

public interface I2FAMembershipProvider
{
    bool ValidateUser2FA(string username, string firstFactor, string secondFactor);
}

Then implement this additional interface in your existing MembershipProvider

public sealed class SampleProvider: MembershipProvider, I2FAMembershipProvider
{
    //Validate 2FA requests with both factors simultaneously
    public bool ValidateUser2FA(string username, string firstFactor, string secondFactor)
    {
        //... implementation here
    }

    //Traditional single factor authentication
    public override bool ValidateUser(string username, string passcode)
    {
        //... implementation here
    }

Finally, check if the provider supports this interface when validating the credentials when they are posted back to the server:

if (Membership.Provider is I2FAMembershipProvider)
{
    //Validation using enhanced interface
    if (((I2FAMembershipProvider) Membership.Provider).ValidateUser2FA(username, password, passcode))
    {
        FormsAuthentication.RedirectFromLoginPage(username, false);
    }
}
else
{
    //Traditional membership provider validation
    if (Membership.ValidateUser(username, password))
    {
        FormsAuthentication.RedirectFromLoginPage(username, false);
    }
}

2