40

There are a few threads here at so about this matter but most of them are outdated and the reference links in them are even more outdated.

I got this website which I need to connect to an external sql server (mssql) with it's own table structure, using the default asp.net membership provider structure is not an option. The table layout is really simple and the usertable looks like this (it's called Individuals)

Individuals
- UserGuid (uniqueidentifier/guid, unique)
- Name (varchar)
- Password (varchar)
- HasAccess (tinyint/ 1 or 0)
- DateTime (datetime)
- Log (xml)

The required functionality is simply to log someone in, the rest is not necessary :)

I followed some guides but most of them are outdated and very complex. Unfortunately the msdn examples follows this pattern and the documentation is not very good.

So if anyone got some resources showing how to, or are willing to post codesamples or similar here I'd appreciate it.

Thanks!

user850010
  • 5,990
  • 12
  • 34
  • 57
Eric Herlitz
  • 22,490
  • 25
  • 106
  • 149
  • I've searched for simple provider many times. And always found something overcomplicated. So I decided to create my own just 5 classes. See http://github.com/TesserisPro/ASP.NET-SImple-Security-Provider – Dmitry Aug 19 '14 at 10:16

2 Answers2

61

It's very simple really:

  1. Create a new Class file (if you're not using a multi-layered system, in your project's Models folder) let's called MyMembershipProvider.cs

  2. Inherit that class from System.Web.Security.MembershipProvider

  3. automatically create the needed methods (period + space in the inherit class)

Done!

All methods will have the NotImplementedException exception, all you need to do is edit each one and put your own code. For example, I define the GetUser as shown below:

public override MembershipUser GetUser(string username, bool userIsOnline)
{
    return db.GetUser(username);
}

dbis my Database Repository that I added into the class as

MyServicesRepository db = new MyServicesRepository();

there, you will find the GetUser method as:

public MembershipUser GetUser(string username)
{
    OS_Users user = this.FindUserByUsername(username);

    if (user == null)
        return
        new MembershipUser(
            providerName: "MyMembershipProvider",
            name: "",
            providerUserKey: null,
            email: "",
            passwordQuestion: "",
            comment: "",
            isApproved: false,
            isLockedOut: true,
            creationDate: DateTime.UtcNow,
            lastLoginDate: DateTime.UtcNow,
            lastActivityDate: DateTime.UtcNow,
            lastPasswordChangedDate: DateTime.UtcNow,
            lastLockoutDate: DateTime.UtcNow);

    return
        new MembershipUser(
            providerName: "MyMembershipProvider",
            name: user.username,
            providerUserKey: null,
            email: user.email,
            passwordQuestion: "",
            comment: "ANYTHING you would like to pass",
            isApproved: true,
            isLockedOut: user.lockout,
            creationDate: user.create_date,
            lastLoginDate: user.lastLoginDate,
            lastActivityDate: user.lastActivityDate,
            lastPasswordChangedDate: user.lastPasswordChangedDate,
            lastLockoutDate: user.lastLockoutDate);
}

Do this for all the methods you use (debug the project and see which ones you need) - I only use some, not all as I don't really care about methods like ChangePasswordQuestionAndAnswer, DeleteUser, etc

just make sure that in your web.config you add the new Membership as:

<membership defaultProvider="MyMembershipProvider">
  <providers>
    <clear/>
    <add name="MyMembershipProvider" type="Your.NameSpace.MyMembershipProvider" connectionStringName="OnlineServicesEntities"
         enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
         maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
         applicationName="/" />
  </providers>
</membership>

You have a nice Video Tutorial from Chris Pels (dated 2007 but still mostly valid) and code for this as well, though Video Tutorial is in VB, but let's you understand the steps...

http://www.asp.net/general/videos/how-do-i-create-a-custom-membership-provider

I did not only create my own Membership Provider but I created my Roles Provider as well, witch as you can see from above code, is as simple as the MemberShip and let's you, in your application use things like:

[Authorize(Roles = "Partner, Admin")]
public ActionResult MyAction()
{

}

and

@if (Roles.IsUserInRole(Context.User.Identity.Name, "Admin"))
{
    <div>You're an ADMIN, Congrats!</div>
}

What is automagically create the needed methods (period + space in the inherit class)

You can either right-click, or have the cursor on the name and press Control + . and then space.

Zax
  • 2,612
  • 6
  • 44
  • 69
balexandre
  • 69,002
  • 44
  • 219
  • 321
  • Thanks, do I still need to install the aspnet schemas (the ones used by the membership provider) and other stuff to my remote database? – Eric Herlitz Apr 19 '11 at 10:05
  • No... the class has no connection to the Database Schema, you implement that. For example, I requested my own Database / My own tables `OS_Users` in my example to give me the user and as long as you pass a `MembershipUser` you're fine. --> See that screencast Video that I posted in the answer first, so you get what's this is all about. – balexandre Apr 19 '11 at 10:18
  • Can anyone elaborate on #3 at the top, "automagically create the needed methods (period + space in the inherit class)"? I'm not familiar with that shortcut. What does that mean? – Michael Dec 19 '11 at 20:38
  • 1
    @Michael A few months late, but since I just figured this out myself yesterday, thought I'd share: you can "automagically" create the methods and properties that must be inherited by right-clicking "MembershipProvider" in your class heading (public class MyMembershipProvider : MembershipProvider) --- there will be an option to generate stubs for the necessary inherited stuff. All stubs automatically are filled in with NotImplementedExceptions(), which you can either leave that way, or remove and implement where necessary. – CptSupermrkt Feb 07 '12 at 00:13
  • 1
    instead of right-click, you can have the cursor on the name and press `Control` + `.` and then `space`. – balexandre Feb 07 '12 at 07:23
  • 3
    BTW, this requires a reference to System.Web.ApplicationServices.dll – Eric J. Apr 04 '12 at 01:44
  • How would would handle the hashing of passwords in this case? Can the base Membership provider be tapped into to handle this? – Mike Cole Jul 12 '12 at 05:25
  • @EricJ. also a reference to System.Configuration – THBBFT Feb 22 '15 at 18:11
0

There are a few threads here at so about this matter but most of them are outdated and the reference links in them are even more outdated.

Since the introduction of ASP.NET in Framework 1.0 the Page.User/CurrentSession.User/IPrincipal/IIdentity model is unchanged. In Framework 2.0 the Membership provider was added. Those "outdated" reference remain valid guidance. MSDN

Cos Callis
  • 4,931
  • 3
  • 23
  • 55