ASP.NET MVC 2 and MongoDb Part 3 – Custom membershipprovider

Out of the box you can easily implement a user management system in a ASP.NET MVC (2) application with very little effort. You can use the SqlMembershipProvider which will create a database for you with tables for maintaining users and their roles. But what if you don't use SQL as a backend but Mongo instead?
Then you need to implement your own custom membership provider. Here are the steps to do just that.

NB: This is just to get you started! It's not a very tightly secured authentication system, so don't use this in production. In production you'll probably want to use SSL and encrypted passwords.

In ASP.NET MVC it is possible to secure controller actions, like this:

[RequiresAuthentication]
public ActionResult Index()
   {
      var session = new MongoSession();
         {
           var userlist = session.users.AsEnumerable();
           return View(userlist);
         }
  }

By adding the RequiresAuthentication attribute above the controller method 'Index', the /User/Index page is secured.

To accomplish this, we need to take the following steps:

  • Add the authentication attribute class
  • Add a membership class which implements the MembershipProvider interface
  • Add a Controller and a View
  • Modify web.config

Let's start with the RequiresAuthenticationAttribute class, which inherits from the ActionFilterAttribute:

public class RequiresAuthenticationAttribute : ActionFilterAttribute
 {
   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
      //redirect if not authenticated
      if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
           //use the current url for the redirect
          string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;

           //send them off to the login page
          string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);
          string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
          filterContext.HttpContext.Response.Redirect(loginUrl, true);
     }
   }
}

Now that we have this class defined, let's create our custom membershipprovider class.
Firstly, create a class with the name 'BugBaseMembership' and let it implement the MembershipProvider interface:

implement membershipprovider interface

Now scroll down to the last method:

implement3

Here you can implement your own validate user method. And our backend is of course MongoDb so here we go:

public override bool ValidateUser(string email, string password)
 {
   using (var session = new MongoSession())
    {
      User user = session.users
       .Where(u => u.Email == email && u.Password == password).FirstOrDefault();
       if (user == null) return false;
          else  return true;
     }
 }

Next, create an AccountController and implement the Login method:

namespace BugBase.Controllers
{
    public class AccountController : Controller
    {
        public ActionResult Logon()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Logon(string email, string password, string returnUrl)
        {
            // Basic parameter validation
            if (String.IsNullOrEmpty(email))
            {
                ModelState.AddModelError("email", "You must specify a mailaddress.");
            }
            if (String.IsNullOrEmpty(password))
            {
                ModelState.AddModelError("password", "You must specify a password.");
            }

            if (ViewData.ModelState.IsValid)
            {

                BugBaseMembership provider = new BugBaseMembership();
                bool loginSuccessful = provider.ValidateUser(email, password);

                if (loginSuccessful)
                {
                    SetAuthenticationCookie(email);
                    return RedirectToAction("Index", "Bug");
                }

                else
                {
                    ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form

            return View();

        }

        public virtual void SetAuthenticationCookie(string username)
        {
            FormsAuthentication.SetAuthCookie(username, false);
        }

        public void Logoff()
        {
            FormsAuthentication.SignOut();
            Response.Redirect("/");
        }
    }
}

When the logon is successfull, you are directed to /Bugs/Index and the authentication is set. Which means that you can retrieve the logonname from the user during the session (User.Identity.Name returns the current logon name).

We're not there yet. We have create a View for the user to enter Username and Password.
It should be strongly typed View and derive from the BugBase.Models.User class.

<label for="email">email</label>
<label for="password">password</label>
<input type="submit" value="Log in" />

There is one thing left to do. We need to plug our custom membership system into the website.
Open web.config and add the following in the System.Web section:

implement4

There you go. You just created your own custom membership provider with a MongoDb backend. Pretty easy, no?

You can download the codesample here.

9 Replies to “ASP.NET MVC 2 and MongoDb Part 3 – Custom membershipprovider”

Leave a Reply to cars auction Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.