Migrating from ASP.NET Identity to SQL Membership

If you crate a new ASP.NET MVC 5 project you have four choices for authentication and one of them is “individual user accounts”. This will create a lot of template code using ASP.NET Identity. This is not the same as classic SQL membership system. New tables will be created in your database.

I was in the situation that I had to work with the classic membership system for compatibility reasons. So what changes must be made to the application?

1. Remove the following from web.config:

<remove name="FormsAuthentication" />

2. Still in web.config, add a connection string and membership and rolemanager sections and set authentication mode to forms:

<connectionStrings>
  <add name="AspNetConnection" connectionString="Data Source=MyServer;Initial Catalog=aspnetdb;…" providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
  <authentication mode="Forms">
    <forms loginUrl="~/Account/Login" name="MyApp" />
  </authentication>
  <membership defaultProvider="SqlMembershipProvider">
    <providers>
      <clear />
      <add 
        name="SqlMembershipProvider" 
        type="System.Web.Security.SqlMembershipProvider" 
        connectionStringName="AspNetConnection" 
        applicationName="MyApp" />
    </providers>
  </membership>
  <roleManager defaultProvider="SqlRoleProvider"
      enabled="true"
      cacheRolesInCookie="true"
      cookieName=".ASPROLES"
      cookieTimeout="30"
      cookiePath="/"
      cookieRequireSSL="true"
      cookieSlidingExpiration="true"
      cookieProtection="All" >
    <providers>
      <clear />
      <add
        name="SqlRoleProvider"
        type="System.Web.Security.SqlRoleProvider"
        connectionStringName="AspNetConnection"
        applicationName="Cassius" />
    </providers>
  </roleManager>
</system.web>

3. In AccountViewModel, you can delete everything but LoginViewModel. LoginViewModel can contain only the following:

public class LoginViewModel
{
    [Required]
    [Display(Name = "User id")]
    public string UserId { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }
}

4. In AccountController, you can delete everything except Login and LogOff. They should look something like this:

//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    return View();
}

//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
     if (!ModelState.IsValid)
     {
          return View(model);
     }

     if (System.Web.Security.Membership.ValidateUser(model.UserId, model.Password))
     {
         System.Web.Security.FormsAuthentication.SetAuthCookie(model.UserId, false);
         return RedirectToLocal(returnUrl);
     }
     else
     {
         ModelState.AddModelError("", "Invalid user name or password.");
         return View(model);
     }
 }

//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
     System.Web.Security.FormsAuthentication.SignOut();
     return RedirectToAction("Index", "Home");
}

5. Login.cshtml can be simplified as well:

@using ResellerData.WebAdmin.Models
@model LoginViewModel
@{
    ViewBag.Title = "Log in";
}
<h2>@ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
        <section id="loginForm">
            @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
            {
                @Html.AntiForgeryToken()
<h4>Use a local account to log in.</h4>

<hr />

@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
                    @Html.LabelFor(m => m.UserId, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
                        @Html.TextBoxFor(m => m.UserId, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.UserId, "", new { @class = "text-danger" })</div>
</div>
<div class="form-group">
                    @Html.LabelFor(m => m.Password, new {@class = "col-md-2 control-label"})
<div class="col-md-10">
                        @Html.PasswordFor(m => m.Password, new {@class = "form-control"})
                        @Html.ValidationMessageFor(m => m.Password, "", new {@class = "text-danger"})</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="Log in" class="btn btn-default" /></div>
</div>
}
        </section></div>
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

6. Then, delete a lot of unecessary files:

  • IdentityConfig.cs
  • Startup.Auth.cs
  • ManageController.cs
  • IdentityModels.cs
  • ManageViewModel.cs
  • Everything under Views\Account except Login.cshtml
  • Everything under Views\Manage
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s