In this article I am going to discuss about how to block login if email is not confirmed in asp.net core identity with web API. In my previous article I have discussed how to implement email confirmation with asp.net core identity in web api. To implement how to block login if email is not confirmed in asp.net core identity firstly you have to check whether the email of user is confirmed or not if not then we have to stop him from log in.

Why to Block Login if Email is not Confirmed in Asp.net Core Identity?

If you did not block login if email is not confirmed in asp.net core identity then anyone can login whether he has confirmed his email or not confirmed his email. Therefore if you want that only authenticated and email confirmed users can log in to your site then this step is important otherwise there is no use of doing email confirmation in your web application. So to implement this feature you have to modify your program.cs file like the following code.

builder.Services.AddIdentity<Users, IdentityRole>(
    options =>
    {
        // Password settings
        options.Password.RequireDigit = true;
        options.Password.RequiredLength = 8;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequireLowercase = true;

        //Email confirm settings
        options.User.RequireUniqueEmail = true;
    
        options.SignIn.RequireConfirmedEmail = true;

    })
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

In Program.cs file we are telling that only user with confirm email and logged in and only user with unique email address can register himself in our web application. Instead of email settings I also done some extra password settings which is used to tell your on the time of registeration that what are the minimum requirements of password.

Check Whether the Email is Confirmed or Not

To check whether the email is confirmed or not in our web application we have to use one in-built method of identity which return true if email is confirmed else return false. For that you have to initialize the userManager with your User Entity and add it into the constructor.

_userManager.IsEmailConfirmedAsync(user)

Now after knowing about the method which is used to check whether the email is confirmed or not. Its time to change the login method of your application with the following code.

        public async Task<LoginResponseViewModel> Login(LoginRequestViewModel model)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user != null && await _userManager.IsEmailConfirmedAsync(user) && await _userManager.CheckPasswordAsync(user, model.Password))
            {
                var userRoles = await _userManager.GetRolesAsync(user);
                var authClaims = new List<Claim>
                    {
                    new Claim(ClaimTypes.Name, user.UserName),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    };

                foreach (var userRole in userRoles)
                {
                    authClaims.Add(new Claim(ClaimTypes.Role, userRole));
                }

                authClaims.Add(new Claim("UserId", user.Id));
                var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));

                var token = new JwtSecurityToken(
                    issuer: _configuration["JWT:ValidIssuer"],
                    audience: _configuration["JWT:ValidAudience"],
                    expires: DateTime.Now.AddHours(3),
                    claims: authClaims,
                    signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
                    );

                return new LoginResponseViewModel
                {
                    Token = new JwtSecurityTokenHandler().WriteToken(token),
                    IsSuccessFul = true,
                    Role = userRoles[0].ToString(),
                    UserName = user.UserName,
                    UserId = user.Id,
                    Email = user.Email,
                };
            }
            return new LoginResponseViewModel
            {
                IsSuccessFul = false,
                Message = "Not Found",
            };
        }

In above code we are checking that if user is not equal to null , email is confirmed and password is right then only he will be able to login otherwise return IsSuccessFul false.

Conclusion

In above article we have discussed how to restrict login if email is not confirmed and in previous article we have discussed how to implement email confirmation in asp.net core identity I must suggest you if you directly come to this article then you will not able to understand how it is going on so you can go through the above link for clear understanding. If you want to study more about email confirmation and security steps then you can go to the official documentation of asp.net core identity.