Change Password Requirements for ASP.NET Identity in Episerver Foundation

Change Password Requirements for ASP.NET Identity in Episerver Foundation

In this short blog post, I will explain how you can add some password restrictions for your users if you are using ASP.NET Identity and as base the Episerver Foundation CMS Solution. So without further due, lets begin.

First, identify the file called IAppBuilderExtensions.cs, it should be located inside the CMS/Extensions folder. The content of the file is the following.

using EPiServer.Cms.UI.AspNetIdentity;
using EPiServer.Core;
using EPiServer.Web.Routing;
using Foundation.Cms.Identity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
using System;

namespace Foundation.Cms.Extensions
{
    public static class AppBuilderExtensions
    {
        public static void ConfigureAuthentication(this IAppBuilder app, string commerceConectionStringName)
        {
            app.AddCmsAspNetIdentity<SiteUser>(new ApplicationOptions
            {
                ConnectionStringName = commerceConectionStringName
            });

            // 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("/util/Login.aspx"),
                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<SiteUser>, SiteUser>(
                            TimeSpan.FromMinutes(30),
                            (manager, user) => manager.GenerateUserIdentityAsync(user)),
                    OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri),
                    OnResponseSignOut = context =>
                        context.Response.Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage))
                }
            });

            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

            // Enables the application to remember the second login verification factor such as phone or email.
            // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
            // This is similar to the RememberMe option when you log in.
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
        }
    }
}

Now, we will add the following line below the app.AddCmsAspNetIdentity invocation inside the ConfigureAuthentication method.

 app.CreatePerOwinContext<ApplicationUserManager<SiteUser>>(CreateApplicationUserManager);

The method CreateApplicationUserManager will be in charge to add the password restrictions. For this, we will create a new application manager with the current user type and then replace the current password validator property with a new one that includes our new requirements.

 public static ApplicationUserManager<TUser> CreateApplicationUserManager<TUser>(
            IdentityFactoryOptions<ApplicationUserManager<TUser>> options,
            IOwinContext context) where TUser : IdentityUser, IUIUser, new()
        {
            var manager = ApplicationUserManager<TUser>.Create(options, context);

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

            return manager;
        }

In this case, we are requesting our users to create passwords with minimum 8 characters, at least one special character, one digit, one lower case letter and one upper case letter. If you do not have the Site User class it looks similar to this.

using EPiServer.Cms.UI.AspNetIdentity;
using Microsoft.AspNet.Identity;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Foundation.Cms.Identity
{
    public class SiteUser : ApplicationUser
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }
    }
}

Finally, the full code with all the modifications will looks like this.

using EPiServer.Cms.UI.AspNetIdentity;
using EPiServer.Core;
using EPiServer.Shell.Security;
using EPiServer.Web.Routing;
using Foundation.Cms.Identity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
using System;

namespace Foundation.Cms.Extensions
{
    public static class AppBuilderExtensions
    {
        public static void ConfigureAuthentication(this IAppBuilder app, string commerceConnectionStringName)
        {
            app.AddCmsAspNetIdentity<SiteUser>(new ApplicationOptions
            {
                ConnectionStringName = commerceConnectionStringName
            });

            app.CreatePerOwinContext<ApplicationUserManager<SiteUser>>(CreateApplicationUserManager);

            // 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("/util/Login.aspx"),
                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<SiteUser>, SiteUser>(
                            TimeSpan.FromMinutes(30),
                            (manager, user) => manager.GenerateUserIdentityAsync(user)),
                    OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri),
                    OnResponseSignOut = context =>
                        context.Response.Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage))
                }
            });

            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

            // Enables the application to remember the second login verification factor such as phone or email.
            // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
            // This is similar to the RememberMe option when you log in.
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
        }

        public static ApplicationUserManager<TUser> CreateApplicationUserManager<TUser>(
            IdentityFactoryOptions<ApplicationUserManager<TUser>> options,
            IOwinContext context) where TUser : IdentityUser, IUIUser, new()
        {
            var manager = ApplicationUserManager<TUser>.Create(options, context);

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

            return manager;
        }
    }
}

And that is it. Now, you can restrict the password format of your ASP.NET Identity users in your solution. If you have any question let me know. I hope it will help someone and as always keep learning !!!

Written by:

Jorge Cardenas

Developer with several years of experience who is passionate about technology and how to solve problems through it.

View All Posts

Leave a Reply