How to change the password requirements for Orchard Core sites

The password requirements for an Orchard Core site are configurable, you just need to know where to look.

Changing the default configuration

The quickest way to change these settings is in the ConfigureServices method in your Startup class. Orchard Core takes the configuration from the IdentityOptions model, and the properties on this model can be set at startup time.

Add the following snippet into your ConfigureServices method:

 services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredUniqueChars = 3;
options.Password.RequiredLength = 6;
});

These values are only for demonstration purposes. You should pick sensible values for you application's needs.

Now, when we build and run, we can see that the password restrictions have been relaxed to what we specified.

Reading configuration from an external config file

The example I gave above is a great way to get going, but ideally we'd want to read configuration from an external file. This allows us to specify different configuration for different environements, transform configuration at build time or deploy time, and it also removes hard coded configuration from our compiled libraries.

Again, this can be done from out Startup class, so lets jump right in.

The first thing we need to do is to add a property to the Startup class. This property will hold our configuration, which we'll later use to tell ASP.NET Core where our configuration files live. The property should look like this:

public IConfiguration Configuration { get; }

The next thing we need to do is to set the value of this property to something useful. This can be done in the constructor:

 public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();

Configuration = builder.Build();
}

At this point, we're basically telling ASP.NET Core where to find the configuration files. We have specified two configuration files, one of which is specifc to the environment we are running on. We aren't consuming the files yet. We haven't even created them yet. 

The next thing to do is to switch out the hard coded configuration that we added above, and replace it with something that will read from the configuration files. This is where our Configuration property comes in.

Change the block we added earlierfrom this:

 services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredUniqueChars = 3;
options.Password.RequiredLength = 6;
});

to this:

 services.Configure<IdentityOptions>(options =>
{
Configuration.GetSection("IdentityOptions").Bind(options);
});

We're now binding the IdentityOptions model to a configuration section with the key IdentityOptions. The Configuration property knows where to find those files, as we told it in the constructor, so the last thing to do is to create a configuration file.

We said that there was a JSON configuration file at the root of the project called appsettings.json, so let's create that file now. The contents should look like this:

{
"IdentityOptions": {
"Password": {
"RequireDigit": false,
"RequireLowercase": true,
"RequireUppercase": true,
"RequireNonAlphanumeric": false,
"RequiredUniqueChars": 3,
"RequiredLength": 6
}
}
}

The second line is the key that we provided to the GetSection() method, and the rest of it models the properties of the IdentityOptions object

Consuming the configuration

If you ever need to access the vales of the configuration, for example in a custom module you are writing, then all you need to do is inject in IOptions<IdentityOptions>. The settings will be available on the Values property of the object that is injected in.

This functionality is standard for ASP.NET Core applications, and you can even create your own configuration models, configure, and consume them in any ASP.NET Core application, not just Orchard Core.

Leave a comment