Tuesday, February 5, 2013

Mvc4 fresh site 'simplemembershipprovider' with existing user login table(s)

So there are a few requirements to using WebMatrix.WebData.SimpleMembershipProvider. One of these is that your PasswordHash must be stored in a column called Password. Argh! I've gotten the login part and only the login part working. Here's my Context:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Globalization;
using System.Web.Security;

namespace Models
  public class UsersContext : DbContext
    public UsersContext()
      : base("DefaultConnection")
      this.Configuration.LazyLoadingEnabled = false; //me no likey.
      Database.SetInitializer<UsersContext>(null); //clear out all the strategies so that EF will leave the existing db ALONE.


    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
      //throw new UnintentionalCodeFirstException(); in the event you don't want code-first

  public class User
    public int UserId { get; set; }

    public string UserName { get; set; }

    public string PasswordHash { get; set; }
No changes made in Global.asax added to configuration system.web :
    <membership defaultProvider="SimpleMembershipProvider">
        <add name="SimpleMembershipProvider" type="PaySpan.Jms.Models.SimpleMembershipProvider,PaySpan.Jms"/>
Here is the derived SimpleMembershipProvider:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Web;
using System.Web.Helpers;
using System.Web.WebPages;

using Payformance.Core.Cryptography;

namespace PaySpan.Jms.Models
  public class SimpleMembershipProvider : WebMatrix.WebData.SimpleMembershipProvider
    // Inherited from MembershipProvider ==> Forwarded to previous provider if this provider hasn't been initialized
    public override bool ValidateUser(string username, string password)
      var userHash = Crypto.HashPassword(password); //if only we were using the default asp hash provider =(
      var ourHash = Hash.HashToString(password);
      Trace.WriteLine("userHash:" + userHash);
      Trace.WriteLine("ourHash:" + ourHash);
        Trace.WriteLine("trying custom validate user");
        using (var db = new UsersContext())
          Trace.WriteLine("trying to get userId/Hash");
          var u=db.Users.Where(up => up.UserName == username).Select(up => new { up.UserId, up.PasswordHash}).FirstOrDefault();

          Trace.WriteLine("tracing user");

          //if (u!=null && Crypto.VerifyHashedPassword(u.PasswordHash,userHash)) return true; // this would be if you want to use the default hash provider
          return u != null && ourHash == u.PasswordHash;

        return base.ValidateUser(username, password);
      catch (Exception ex)
Then in the provided InitializeSimpleMembershipAttribute changed it to
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "User", "User_Id", "User_Name", autoCreateTables: false);

No comments:

Post a Comment