Analysis of the Essence of Microsoft.AspNetCore.Identity - Configuration Details

Posted by snidog on Sun, 21 Jul 2019 09:16:20 +0200

Learning Catalogue

  • Preface
  • primary
    • Rookie Entry
    • Detailed configuration
    • Simple secondary development
  • Advanced
    • UserManager parsing
    • RoleManager parsing
    • Validator parsing
    • SignInManager parsing

Why is there configuration?

Normally, users of any product will do some customized functions according to their own business requirements, such as some want to restrict user names, some need to restrict passwords and so on. Then software developers need to extract the requirements of these functional configurations, and then make system configuration management. In this way, users can configure and manage the personalized requirements themselves.

Can Identity also be configured?

The answer is yes. But Microsoft.AspNetCore.Identity is a framework for developers, not end users, so its configuration needs to be implemented through code.

Open the Startup.cs class and let's do some configuration.

Configure using the second overload of AddDefault Identity.

Configure User Name

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.User = new UserOptions
    {
        RequireUniqueEmail = true, //Require Email to be unique
        AllowedUserNameCharacters = "abcdefgABCDEFG" //Allowed user name character, default is abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+
    };
})

Unfortunately, it doesn't support regular expressions, if you let the user name support Chinese. How many Chinese characters do I have to write in here?

Configure Ciphers

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Password = new PasswordOptions
    {
        RequiredLength = 8, //Require minimum password length, default is 6 characters
        RequireDigit = true, //Require numbers
        RequiredUniqueChars = 3, //Require at least the number of letters to appear
        RequireLowercase = true, //Require lowercase letters
        RequireNonAlphanumeric = true, //Require special characters
        RequireUppercase = true //Require capital letters
    };
})

Lock accounts

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Lockout = new LockoutOptions
    {
        AllowedForNewUsers = true, // New Users Lock Accounts
        DefaultLockoutTimeSpan = TimeSpan.FromHours(1), //Lock-in time, default is 5 minutes
        MaxFailedAccessAttempts = 3 //Maximum number of login errors attempted, default 5 times
    };
})

Database Storage

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Stores = new StoreOptions
    {
        MaxLengthForKeys = 128, // Maximum length of primary key
        ProtectPersonalData = true //Protecting user data requires the implementation of IProtectedUserStore interface
    };
})

If not set, the primary key is the string length of max.

Token Configuration

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Tokens = new TokenOptions
    {
        AuthenticatorIssuer = "Identity", //Certified consumers
        AuthenticatorTokenProvider = "MyAuthenticatorTokenProvider", //Provider of authentication token
        ChangeEmailTokenProvider = "MyChangeEmailTokenProvider", //Token Provider for Replacing Mailboxes
        ChangePhoneNumberTokenProvider = "MyChangePhoneNumberTokenProvider", //Token Provider for Replacing Mobile Phone Number
        EmailConfirmationTokenProvider = "MyEmailConfirmationTokenProvider", //Authenticate the token provider of the mailbox
        PasswordResetTokenProvider = "MyPasswordResetTokenProvider", //A token provider that resets passwords
        ProviderMap = new Dictionary<string, TokenProviderDescriptor>()
    };
})

This part is used for secondary development. These so-called TokenProvider s can be customized, such as how to generate tokens, and how to issue tokens to users and request user authentication.

The mobile phone verification code should be a familiar scene. In the framework, you can't write the code to send the authentication code directly. Instead, you inherit an interface and replace the instance of the interface at the program entrance, so that when you encounter the interface in the framework, you will use your instance to send the mobile phone authentication code.

Declarative configuration

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.ClaimsIdentity = new ClaimsIdentityOptions
    {
        RoleClaimType = "IdentityRole",
        UserIdClaimType = "IdentityId",
        SecurityStampClaimType = "SecurityStamp",
        UserNameClaimType = "IdentityName"
    };
})

If you're still using it Role-based authorization Ways to learn Declarative-based authorization But now there is a more advanced way: Policy-based authorization.

Login Authentication Configuration

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.SignIn = new SignInOptions
    {
        RequireConfirmedEmail = true, //Request activation of mailbox
        RequireConfirmedPhoneNumber = true //Request activation of mobile phone number
    };
})

At the time of login, if the mobile phone number or mailbox is not activated/confirmed, the login cannot be made.

summary

These are all hard-coded configurations. Of course, you can read the configuration from the database and deserialize it to the object, so you only need to modify the configuration file to achieve the goal, but this configuration is completed at injection time, so you also need to update the injected instance. It will take some technical means.

Topics: Mobile Database