This content is archived. See latest version here.

Last updated: Oct 16 2014

Introduction

This section provides information on how to configure AspNet Identity as the authentication provider for EPiServer. This configuration requires the following NuGet packages as dependencies:

  • Microsoft.Owin.Security.Cookies
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.AspNet.Identity.EntityFramework

To configure AspNet Identity OWIN authentication you must set the authentication type in the system.web section of the web.config like below.

XML
<authentication mode="None"></authentication>

To configure AspNet Identity OWIN authentication you must also create an IdentityUser class to hold all the properties of your user. The sample below is using Microsoft.AspNet.Identity.EntityFramework package as the data store. Since we are using EntityFramework we need to also configure a DBContext to persist the data.

C#
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

namespace WebApplication1.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
	public ApplicationUser()
	{
	}

	public ApplicationUser(string username) : base(username)
	{
			
	}

	public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
	{
		// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
		var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
		// Add custom user claims here
		return userIdentity;
	}

		
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
	public ApplicationDbContext() : base("EcfSqlConnection", throwIfV1Schema: false)
	{
	}

	public static ApplicationDbContext Create()
	{
	    return new ApplicationDbContext();
	}
    }
}

To configure AspNet Identity OWIN authentication you must also create a UserManager class. The sample below is using Microsoft.AspNet.Identity.EntityFramework package as the data store and will make use of the ApplicationUser we created in the previous step.

C#
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using WebApplication1.Models;

namespace WebApplication1
{
    // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
    public class ApplicationUserManager : UserManager<ApplicationUser>
    {
		public ApplicationUserManager(IUserStore<ApplicationUser> store)
				: base(store)
		{
		}

		public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
		{
				var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
				// Configure validation logic for usernames
				manager.UserValidator = new UserValidator<ApplicationUser>(manager)
				{
						AllowOnlyAlphanumericUserNames = false,
						RequireUniqueEmail = true
				};

				// Configure validation logic for passwords
				manager.PasswordValidator = new PasswordValidator
				{
						RequiredLength = 6,
						RequireNonLetterOrDigit = true,
						RequireDigit = true,
						RequireLowercase = true,
						RequireUppercase = true,
				};

				// Configure user lockout defaults
				manager.UserLockoutEnabledByDefault = true;
				manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
				manager.MaxFailedAccessAttemptsBeforeLockout = 5;

				// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
				// You can write your own provider and plug it in here.
				manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
				{
						MessageFormat = "Your security code is {0}"
				});
				manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
				{
						Subject = "Security Code",
						BodyFormat = "Your security code is {0}"
				});
			 
				var dataProtectionProvider = options.DataProtectionProvider;
				if (dataProtectionProvider != null)
				{
						manager.UserTokenProvider =
								new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
				}
				return manager;
		}
    }
}

To configure AspNet Identity OWIN authentication you must also create a SignInManager class. The sample below is using Microsoft.AspNet.Identity.EntityFramework package as the data store and will make use of the ApplicationUser we created in the previous step.

C#
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using WebApplication1.Models;

namespace WebApplication1
{
    // Configure the application sign-in manager which is used in this application.
    public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
    {
        public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
            : base(userManager, authenticationManager)
        {
        }

        public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
        {
            return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
        }

        public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
        {
            return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
        }
    }
}

To configure AspNet Identity authentication you must also create a Startup file in your project that will handle the configuration of the AspNet Identity middleware.

C#
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using WebApplication1.Models;

namespace WebApplication1
{
    public partial class Startup
    {
        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext(ApplicationUserManager.Create);
            app.CreatePerOwinContext(ApplicationSignInManager.Create);

            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            // Configure the sign in cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });            
        }
    }
}

To configure AspNet Identity authentication you must also make sure that your users have the proper roles if you want to allow access to edit and admin modes. Microsoft.AspNet.Identity.EntityFramework package automatically adds tables for handling roles when auto migration is on. There is currently no user interface for adding these roles, so you will need to establish your own mechanism of creating and maintaining roles for your users. Below is a sample controller and views on how to add roles to AspNet Identity and assign these roles to a user.

RolesController.cs

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
    /// <summary>
    /// Controller for manipulating roles and role assigment
    /// </summary>
    public class RolesController : Controller
    {

        private ApplicationDbContext _context;
        private ApplicationUserManager _userManager;

        public ApplicationDbContext ApplicationDbContext
        {
            get
            {
                return _context ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>();
            }
            private set { _context = value; }
        }

        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }

        /// <summary>
        /// Action for Index view
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            var roles = ApplicationDbContext.Roles.ToList();
            return View(roles);
        }

        //
        // POST: /Roles/Create
        /// <summary>
        /// Action for create view
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                ApplicationDbContext.Roles.Add(new IdentityRole()
                {
                    Name = collection["RoleName"]
                });
                ApplicationDbContext.SaveChanges();
                ViewBag.ResultMessage = "Role created successfully !";
                return RedirectToAction("Index");
            }
            catch(Exception ex)
            {
                return View();
            }
        }

        [HttpGet]
        public ActionResult Create()
        {
            return View();
        }

        /// <summary>
        /// Action for delete view.
        /// </summary>
        /// <param name="roleName">Name of the role.</param>
        /// <returns></returns>
        public ActionResult Delete(string roleName)
        {
            var thisRole = ApplicationDbContext.Roles.FirstOrDefault(r => r.Name.Equals(roleName, StringComparison.CurrentCultureIgnoreCase));
            ApplicationDbContext.Roles.Remove(thisRole);
            ApplicationDbContext.SaveChanges();
            return RedirectToAction("Index");
        }

        /// <summary>
        /// Action for Edit View.
        /// </summary>
        /// <param name="roleName">Name of the role.</param>
        /// <returns></returns>
        public ActionResult Edit(string roleName)
        {
            var thisRole = ApplicationDbContext.Roles.FirstOrDefault(r => r.Name.Equals(roleName, StringComparison.CurrentCultureIgnoreCase));

            return View(thisRole);
        }

        //
        // POST: /Roles/Edit/5
        /// <summary>
        /// Post Action for edit view.
        /// </summary>
        /// <param name="role">The role.</param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(IdentityRole role)
        {
            try
            {
                ApplicationDbContext.Entry(role).State = System.Data.Entity.EntityState.Modified;
                ApplicationDbContext.SaveChanges();

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        /// <summary>
        /// Action for ManageUserRoles view.
        /// </summary>
        /// <returns></returns>
        public ActionResult ManageUserRoles()
        {
            // prepopulat roles for the view dropdown
            var list = ApplicationDbContext.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = list;
            return View();
        }

        /// <summary>
        /// Action for posting role to add to user.
        /// </summary>
        /// <param name="UserName">Name of the user.</param>
        /// <param name="RoleName">Name of the role.</param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult RoleAddToUser(string UserName, string RoleName)
        {
            var user = ApplicationDbContext.Users.FirstOrDefault(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase));
            UserManager.AddToRole(user.Id, RoleName);
            ViewBag.ResultMessage = "Role created successfully !";
            // prepopulat roles for the view dropdown
            var list = ApplicationDbContext.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = list;

            return View("ManageUserRoles");
        }

        /// <summary>
        /// Action Gets the roles for the user.
        /// </summary>
        /// <param name="UserName">Name of the user.</param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult GetRoles(string UserName)
        {
            if (!string.IsNullOrWhiteSpace(UserName))
            {
                var user = ApplicationDbContext.Users.FirstOrDefault(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase));
                ViewBag.RolesForThisUser = UserManager.GetRoles(user.Id);

                // prepopulat roles for the view dropdown
                var list = ApplicationDbContext.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
                ViewBag.Roles = list;
            }

            return View("ManageUserRoles");
        }

        /// <summary>
        /// Action Deletes the role for user.
        /// </summary>
        /// <param name="UserName">Name of the user.</param>
        /// <param name="RoleName">Name of the role.</param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteRoleForUser(string UserName, string RoleName)
        {
            var user = ApplicationDbContext.Users.FirstOrDefault(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase));

            if (UserManager.IsInRole(user.Id, RoleName))
            {
                UserManager.RemoveFromRole(user.Id, RoleName);
                ViewBag.ResultMessage = "Role removed from this user successfully !";
            }
            else
            {
                ViewBag.ResultMessage = "This user doesn't belong to selected role.";
            }
            // prepopulat roles for the view dropdown
            var list = ApplicationDbContext.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = list;

            return View("ManageUserRoles");
        }
    }
}
Create.cshtml
@{
	ViewBag.Title = "Create";
}

<h2>Create Role</h2>
@Html.ActionLink("List Roles", "Index") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr />
@using (Html.BeginForm())
{
	@Html.AntiForgeryToken()
	@Html.ValidationSummary(true)

	<div>
		Role name
	</div>
	<p>
		@Html.TextBox("RoleName")
	</p>
	<input type="submit" value="Save" />
}
Edit.cshtml
@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
	ViewBag.Title = "Edit";
}

<h2>Edit Role</h2>

@Html.ActionLink("List Roles", "Index") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr />
@using (Html.BeginForm())
{
	@Html.AntiForgeryToken()
	@Html.ValidationSummary(true)
	@Html.HiddenFor(model => model.Id)
	<div>
		Role name
	</div>
	<p>
		@Html.TextBoxFor(model => model.Name)
	</p>
	<input type="submit" value="Save" />
}
Index.cshtml
@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
	ViewBag.Title = "Index";
}

<h2>Roles Listing </h2>

@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr />
<div>
	@foreach (var role in Model)
	{
		<p>
			<strong>@role.Name | </strong>
			<span onclick="return confirm('Are you sure to delete?')"><a href="/Roles/Delete?RoleName=@role.Name" class="delLink" style="color:red;">Delete</a></span> |
			@Html.ActionLink("Edit", "Edit", new { roleName = @role.Name })
		</p>
	}
</div>

ManageUserRoles.cshtml
@{
	ViewBag.Title = "ManageUserRoles";
}

<h2>Manage User Roles</h2>
@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr />

<h2>Role Add to User</h2>

@using (Html.BeginForm("RoleAddToUser", "Roles"))
{
	@Html.AntiForgeryToken()
	@Html.ValidationSummary(true)

	<p>
		Username : @Html.TextBox("UserName")
		Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")

	</p>

	<input type="submit" value="Save" />
}
<hr />
<h3>Get Roles for a User</h3>
@using (Html.BeginForm("GetRoles", "Roles"))
{
	@Html.AntiForgeryToken()
	<p>
		Username : @Html.TextBox("UserName")
		<input type="submit" value="Get Roles for this User" />
	</p>
}

@if (ViewBag.RolesForThisUser != null)
{
	<div style="background-color:yellow;">
		<h3>Roles for this user </h3>
		<ol>
			@foreach (string s in ViewBag.RolesForThisUser)
			{
				<li>@s</li>
			}
		</ol>
	</div>
}

<hr />
<h3>Delete A User from a Role</h3>

@using (Html.BeginForm("DeleteRoleForUser", "Roles"))
{
	@Html.AntiForgeryToken()
	@Html.ValidationSummary(true)

	<p>
		Username : @Html.TextBox("UserName")
		Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")

	</p>

	<input type="submit" value="Delete this user from Role" />
}

See also

Comments

If you are going to post these examples you really must make sure the code works, there's numerous bugs including a missing action in the roles bits listed.

Can you be more specific I used the code to put roles and assign users to roles when preparing the documentation. It could be the formatting got messed up when putting into the code blocks.

The code samples should all be working please let me know if you see any other errors

Full example can be found here:  http://sveinaandahl.blogspot.no/2015/08/how-to-integrate-aspnet-identity-with.html