ASP. NET Core Identity hands on (1)--identity first Experience

Source: Internet
Author: User
Tags compact hmac

The ASP. NET core identity is the membership system for building an ASP. NET core Web application, including membership , login, and user data storage

This is an official introduction from the ASP. NET Core Identity Warehouse Home page, if you are a new and you may not understand what membership is, let me explain that membership is translated by membership , membership has membership, Membership, membership and other relevant meanings, we can be simple and direct but not very appropriate to understand the user management system

The ASP. NET Core Identity (hereinafter referred to as identity), since it can be understood as a user management system, then she is naturally very powerful, including all aspects of user management, in simple terms include:

    1. User data storage (using any of your favorite relational databases, from Sqllite to MySQL, SQL Server, etc., supported by entity Framwork)
    2. Login, register plus identity authentication (cookie-based authentication, if you use VS, you can also generate a user interface and process code for registering logins)
    3. Role management
    4. Claims-based authentication mode Claims Based authentication(If you don't know what claim is, it's okay to remember the word first)

OK identity so good, what exactly does she look like? How do I use it, then we'll do a little demo experience, while doing, while explaining

Software preparation
    • Visual Studio 2017 (the newer the better, if you don't have to download the Vs2017 Community Edition, the installation is fast, compatible with the old version, completely free portal)
Hands-on.

Open VS's Create new project panel select. NET Core, ASP.

Select Web application (Model View Controller)--Change identity--Personal user account
After that, the SQL Server Compact is used by default to store user data

By Ctrl+F5 running the project

Notice the register and login in the upper-right corner? The identity is automatically added to the project when we choose Personal Authentication , and it generates

    • Account Controller ( AccountController registration and login-related codes are here)
    • Login Registration page (Other such as: confirmation email, access restrictions, etc.)
    • Management Controller ( ManageController This is for registered users, mainly has two functions, change password and two-factor authentication)
    • Identity doesn't give you an admin interface.

Click Register to enter the registration interface, the interface looks good, even can be used directly, and then we register an account

When you click on the Register button, you will be redirected to the database migration (if you have used EF Core, you will not feel unfamiliar with this concept) confirmation page

After the app is migrated, you'll have to wait a moment to refresh the page, and during that time, I suggest you look at the information on the migration page
If you don't understand, see

OK, after the migration, you will be back to the homepage, the upper right corner of the registration will become your mailbox and logout link, click on your account mailbox, first see what's Inside

The content of this page is in ManageController , if you do not know what the two-factor authentication Two-factor Authentication is, it's okay, in the subsequent talk about it

Click the Send verification email link, don't worry, don't really send the message

Identity provides e-mail authentication, which is usually the kind of message that has an encrypted link to verify the message, how to generate the link, the identity is already done, and even writes the interface for sending the message-- IEmailSender and an empty implementationEmailSender

namespace IdentityDemo.Services{    public interface IEmailSender    {        Task SendEmailAsync(string email, string subject, string message);    }}
View Database

Just now we have registered a new user, then where does the user save? The default storage is SQL Server Compact, and then we find it and see how identity Designs User data, and I think it's best to learn a new technology by first looking at what it does to save the data.

Connect to the database by selecting Tools, in the menu above vs

Ok, where is the default database location? What's the name of the database? Now, close this window and open the configuration file under the project root directory appsettings.json

{  "ConnectionStrings": {    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IdentityDemo-E3266F7D-D9FD-4038-9AF7-773A31FC3680;Trusted_Connection=True;MultipleActiveResultSets=true"  },  "Logging": {    "IncludeScopes": false,    "LogLevel": {      "Default": "Warning"    }  }}

We can see the name of our database aspnet-IdentityDemo-E3266F7D-D9FD-4038-9AF7-773A31FC3680 , and his position is C:\Users\{当前登录的用户名}\ below. Do it again, then click Continue to select your database file

This may encounter a situation where the database file is occupied

This is because the program that just started does not exit, if you are using self-hosted boot, then close it if you use iisexpress, also close it

All right, let's see what's in the database.

_EFMigrationsHistoryThe Migration history table for EF doesn't have to follow this table

AspNetUserClaims, AspNetRoleClaims is the user and role of the Declaration table, before we mentioned that the Identity is based on the Claims authentication mode (Claims Based authentication), claim in which plays a very important role, Even roles are converted into Claim,claim related will be explained later, if you do not understand it, do not worry

AspNetUsers, AspNetRoles and AspNetUserRoles Store user and role information

AspNetUserTokens, AspNetUserLogins stored in the user's use of the external login provider's information and tokens, external login provider refers to such as microblogging, QQ, Google, Microsoft, such as the provision of OAuth or OpenID connect to the manufacturer. For example, Segmentfault can use Weibo to login

And then we're going to explain the most important table.AspNetUsers

User Data Core Storage--aspnetusers

The actual data for the newly registered user is as follows

Blog Park does not support the horizontal scrolling code, so I put the code to come up, looking a bit awkward or you can go here to see the specific data

Id------------------------------------d4929072-e704-447c-a9aa-e1b7f510 Fd37 accessfailedcount-----------------0 concurrencystamp------------------ ------------------5765da8f-1945-40c6-8f81-97604739e5ec Email-----------------[email protected] Ema Ilconfirmed--------------0 lockoutenabled--------------1 lockoutend----------NULL Normaliz   Edemail-----------------[email protected] Normalizedusername------------------[email protected] PasswordHash-------------------------------------- ----------------------------------------------aqaaaaeaaccqaaaaehq+       3z9h0tiusinnps8b99skaqbxh0zcwlgwtgtvik6s85viewqfv8tf8brydtw8rw==phonenumber-----------NULL Phonenumberconfirmed--------------------0 Securitystamp------------------------------------a4d9c858-cc08-4ceb-8d5d-92a6cb1c40b8twofactorenabled----------------0 UserName---   --------------[email protected]
Id

The primary key defaults to nvarchar (450) but is actually the stored GUID string, and it is worth mentioning that the ID is created at the time

The GUID of the primary key is generated in the constructor when the user is created

namespace Microsoft.AspNetCore.Identity{    public class IdentityUser : IdentityUser<string>    {        public IdentityUser()        {            Id = Guid.NewGuid().ToString();        }

This is a small piece of source code, to prove the above content

That is, it is a completely random unordered GUID, then it may be the hidden danger is that when the user is very large, the creation of the user may be slow, but for the vast majority of scenarios, it is unlikely (there are so many users), of course, this may happen, so in subsequent articles, I'll explain how to use bigint as the primary key

Accessfailedcount

This is used to record the number of times a user attempts to log in but failed to log on, and we can use this to determine when to lock the user.

Concurrencystamp

The synchronization token, which must change the value of this column whenever the user record is changed, actually stores the GUID, and initializes the random value directly on the property when the user model is created

public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();

Also note that the value of this column is changed by the time it is manually written in the program, not by the database change (perhaps considering that not all EF-supported databases support timestamp or rowversion types)

Email, Normalizedemail

E-mail is email,normalizedemail is standardized email
What is normalization?
In the user we just created, you can see that normalizedemail just turns the value of email into uppercase, and I think you've got it all figured out.

Indeed, this will improve the efficiency of the database query, from the identity of the code can be seen, about the email query has been converted to Normalizedemail query. Word ..., let's look at a short piece of code.

namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore{        public override Task<TUser> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken = default(CancellationToken))        {            // 略...            return Users.FirstOrDefaultAsync(u => u.NormalizedEmail == normalizedEmail, cancellationToken);        }

NormalizedEmailYou don't have to worry about it when you use it, and you don't have to change its value manually because it's automatically updated when users create or update their profile . NormalizedEmail

And then we still take a look at the source code code

namespace Microsoft.AspNetCore.Identity{    public class UserManager<TUser> : IDisposable where TUser : class    {        public virtual async Task<IdentityResult> CreateAsync(TUser user)        {            // 略...            await UpdateNormalizedUserNameAsync(user);            await UpdateNormalizedEmailAsync(user);            return await Store.CreateAsync(user, CancellationToken);        }        protected virtual async Task<IdentityResult> UpdateUserAsync(TUser user)        {            // 略...            await UpdateNormalizedUserNameAsync(user);            await UpdateNormalizedEmailAsync(user);            return await Store.UpdateAsync(user, CancellationToken);        }
UserName, Normalizedusername

Username is username Normalizedusername or username after normalization, that is, converting to uppercase
Their behavior and the above-mentioned Email, normalizedemail consistent, do not repeat the

Emailconfirmed

The message has been confirmed, this is a bit (bool) type of column, the previous article refers to the identity contains the send and verify the confirmation message function, when the user is created by default, this value is false, confirm that the link is generated by identity, and then sent to Iemailsender. Ok, half of the tasks are done here, and a little piece of code will give you a clearer picture of the process.

public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null){    //略...    var user = new ApplicationUser { UserName = model.Email, Email = model.Email };    var result = await _userManager.CreateAsync(user, model.Password);    if (result.Succeeded)    {        var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);        var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);        await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);        略...        

The code is generated when the project is created and belongs to your project, not the identity.

You may think that after registering we have successfully entered the system, and has not been blocked, even if we did not confirm the mail, the data in the database also indicates that the message is not confirmed

Indeed, because this is not in the identity of the scope, this is our program logic, to prevent unauthenticated mail users to log in, we need to do, but, very simple, only need to write a few lines of code at the time of landing, here for the moment not to start the discussion

Lockoutenabled, Lockoutend

Their data type is bit and DateTimeOffset (7), lockoutenabled Indicates whether this user can be locked, lockoutend specifies the expiration date of the lock, null or a past time, which means that the user is not locked

It is important to note that the identity provides us with the infrastructure for locking, but it is the logic of our program to prevent users from logging in after the user has been locked out.

PasswordHash

Password hash, the identity of the use of the hash strength is relatively high, the difficulty of brute force is very large

=======================HASHED PASSWORD FORMATS=======================Version 2:PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations.(See also: SDL crypto guidelines v5.1, Part III)Format: { 0x00, salt, subkey }Version 3:PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations.Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }(All UInt32s are stored big-endian.)

Version 2 and 3 are for compatibility with identity V1 V2 and V3 their correspondence is as follows

    • V1, v2, Version 2
    • Version 3, v3
Securitystamp

The security token, a random value, must change the value of this item when the user credential-related content changes, the fact that the GUID is stored
The timing of this change is:

    • User-Created
    • change user name
    • Remove external Login
    • Set/Change Message
    • Set/Change phone number
    • Set/Change two-factor verification
    • Change Password
      ConcurrencyStamp SecurityStamp is also changed by code control in the program.
PhoneNumber, phonenumberconfirmed

Telephone and telephone confirmed, easy to understand

Twofactorenabled

Indicates whether the current user has two-factor authentication turned on

This is the end of the first experience:)

This article has been synced to my segmentfault column. NET core Web Dev
ASP. NET Core Identity hands on (1)--identity first Experience

ASP. NET Core Identity hands on (1)--identity first Experience

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.