1

I am using the Membership Provider in ASP.NET MVC and for most data access I use nHibernate and a repository pattern. Do you recommend using a Facade over the Membership Provider so I can create a repository and make it operate a bit more inline with the rest of my entity model? I also have added additional functionality like the ability to add functions to a role and creating the facade would make the classes all a bit nicer.

What have other people done with Membership Provider?

Craig
  • 36,306
  • 34
  • 114
  • 197

2 Answers2

0

You can implement your own MembershipProvider for the site, by inheriting the MembershipProvider base class. Then just override the methods you need to perform the data access through nHibernate.

The only function you really have to implement is ValidateUser. The rest is dependent on the functionality you use in the site relating to the MembershipProvider.

chrispr
  • 336
  • 2
  • 6
0

I have solved this exact problem. In the following manner:

web.config:

<authentication mode="Forms">
  <forms name="APPAUTH"
         defaultUrl="/webapp/Home.mvc"
         loginUrl="/webapp/Session.mvc/Login"
         protection="All"
         timeout="30"
         path="/"/>
</authentication>
<authorization>
  <deny users="?"/>
</authorization>

<location path="Session">
  <system.web>
    <authorization>
      <allow users="*"/>
    </authorization>
  </system.web>
</location>

Then I hook Application_AuthenticateRequest something along the lines of:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];

    if (null == authCookie)
    {
        //no authentication cokie present
        return;
    }

    FormsAuthenticationTicket authTicket = null;
    try
    {
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch (Exception)
    {
        // Can't do anything if we can't decrypt the ticket so treat it as not there
        FormsAuthentication.SignOut(); // Remove bad ticket
    }

    if (authTicket == null)
    {
        //could not decrypt cookie
        return;
    }

    // get the role
    string[] roles = authTicket.UserData.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

    // Set the security context
    ISecurityService security = ContainerProvider.RequestContainer.Resolve<ISecurityService>();
    Models.User user = security.GetUser(authTicket.Name);

    if (user == null)
    {
        FormsAuthentication.SignOut();
        throw new HttpException((int)System.Net.HttpStatusCode.Unauthorized, "Session expired!");
    }

    AppIdentity id = new AppIdentity(user, !authTicket.Expired);
    AppPrincipal principal = new AppPrincipal(id, roles);

    Context.User = principal;
} 

The ContainerProvider.RequestContainer.Resolve<ISecurityService>(); call is to a Autofac container, but you can do anything you need to / want to here.

The AppIdentity and AppPrincipal classes are custom so I can access my roles, but they are not that complicated.

Andrew Burns
  • 13,917
  • 9
  • 40
  • 42