Thursday, February 7, 2019

Simplistic Custom Sign In in MVC


To implement a very simple authentication in MVC where authentication is done using values stored in web.config files follow these steps.

1)     Create a folder Identity and create classes CustomSignInManager, CustomUser, CustomUserManager and CustomUserStore



CustomSignInManager class has the following code:

public class CustomSignInManager : SignInManager<CustomUser, string>
    {
        public CustomSignInManager(CustomUserManager userManager, IAuthenticationManager authenticationManager)
            : base(userManager, authenticationManager)
        {

        }

        public static CustomSignInManager Create(IdentityFactoryOptions<CustomSignInManager> options, IOwinContext context)
        {
            return new CustomSignInManager(context.GetUserManager<CustomUserManager>(), context.Authentication);
        }

        public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
        {
            //return base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout);
            var signInStatus = SignInStatus.Failure;
            if (ConfigurationManager.AppSettings["UserName"].Trim().ToLower() == userName.Trim().ToLower() && ConfigurationManager.AppSettings["Password"] == password)
            {
                signInStatus = SignInStatus.Success;
            }
            return Task.FromResult(signInStatus);
        }
    }


CustomUser class has the following code:

public class CustomUser : IUser<string>
    {
        public string Id { get; set; }

        public string UserName { get; set; }

        public string UserRole { get; set; }
    }

CustomUserManager class has the following code:


public class CustomUserManager : UserManager<CustomUser>
    {
        public CustomUserManager(IUserStore<CustomUser> store) : base(store)
        {
        }

        public static CustomUserManager Create()
        {
            var manager = new CustomUserManager(new CustomUserStore());
            return manager;
        }
    }



CustomUserStore class has the following code:


public class CustomUserStore : IUserStore<CustomUser>
    {
        public CustomUserStore()
        {
            //this.database = new CustomDbContext();
        }

        public void Dispose()
        {
            //this.database.Dispose();
        }

        public Task CreateAsync(CustomUser user)
        {
            // TODO
            throw new NotImplementedException();
        }

        public Task UpdateAsync(CustomUser user)
        {
            // TODO
            throw new NotImplementedException();
        }

        public Task DeleteAsync(CustomUser user)
        {
            // TODO
            throw new NotImplementedException();
        }

        public async Task<CustomUser> FindByIdAsync(string userId)
        {
            await Task.Delay(0);
            return new CustomUser();
        }

        public async Task<CustomUser> FindByNameAsync(string userName)
        {
            await Task.Delay(0);
            return new CustomUser();
        }
    }


Add a property CustomSignInManager to AccountsController

public CustomSignInManager CustomSignInManager
        {
            get { return _signInManager ?? HttpContext.GetOwinContext().Get<CustomSignInManager>(); }
            private set { _signInManager = value; }
        }

Login method in AccountsController class has the following code:


if (!ModelState.IsValid)
            {
                return View(model);
            }
            //Authenticate the user
            var result = await CustomSignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
            switch (result)
            {
                case SignInStatus.Success:
                    var user = new CustomUser() {Id= "1", UserName = model.Email };
                    await CustomSignInManager.SignInAsync(user, model.RememberMe, false);
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "Invalid login attempt.");
                    return View(model);
            }

No comments:

c# httpclient The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch

 If we get this error while trying to get http reponse using HttpClient object, it could mean that certificate validation fails for the remo...