Search code examples
c#entity-frameworkasp.net-mvc-5asp.net-identity

MVC (ASP.NET Identity) custom Signin Status with Entity Framework


I have an existing database using Entity Framework. Registration and Login works, but I would like to add an additional status to the Signin Statuses : UnAuthorized.

Below is the code for logging in :

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
      {
          if (!ModelState.IsValid)
          {
              return View(model);
          }

          // This doesn't count login failures towards account lockout
          // To enable password failures to trigger account lockout, change to shouldLockout: true
          var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
          switch (result)
            {
              case SignInStatus.Success:
                  return RedirectToLocal(returnUrl);
              'case SignInStatus.UnAuthorized:
                  return View("UnAuthorized");' //I want to add this
              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);
          }
      }

I have added the part in the code snippet above to show you what I want. I found the statuses used above. provided in the code snippet below, but I am not able to modify this file :

namespace Microsoft.AspNet.Identity.Owin
{
    //
    // Summary:
    //     Possible results from a sign in attempt
    public enum SignInStatus
    {
        //
        // Summary:
        //     Sign in was successful
        Success = 0,
        //
        // Summary:
        //     User is locked out
        LockedOut = 1,
        //
        // Summary:
        //     Sign in requires addition verification (i.e. two factor)
        RequiresVerification = 2,
        //
        // Summary:
        //     Sign in failed
        Failure = 3
    }
} 

I might add that I am new to MVC.

Could anyone point me into the right direction to be able to add custom signin statuses ? PS: An Authorized field does exist in my DB, which is where I want to pick up if the User is Authorized or not to log in.

Thanks for the help.


Solution

  • So I googled quite a bit and it seems that the Status's for the SignInManager can not be modified ? Perhaps I am wrong, as I have very limited knowledge of MVC and Entity Framework.

    So I found a work around and did my own validations using LinQ by adding the following before the actual login code is run :

    using (EFNameEntities db = new EFNameEntities())
            {
               var UserData = from ANU in db.AspNetUsers
                               where ANU.UserName == model.UserName
                               select new
                               {
                                   ANU.isAuthorized,
                                   ANU.isActive
                               };
    
                foreach (var c in UserData)
                {
                    //If User is NOT Authorized to log in
                    if (!Convert.ToBoolean(c.isAuthorized))
                    {
                        ModelState.AddModelError("", "This User is not Authorized to Login.");
                        return View(model);
                    }
                    else
                    {
                        //If User is NOT Active
                        if (!Convert.ToBoolean(c.isActive))
                        {
                            ModelState.AddModelError("", "This User is not Active.");
                            return View(model);
                        }
                    }
                }
    
    
            }
    

    So the entire Login ActionResult looks like this :

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
    
            using (EFNameEntities db = new EFNameEntities ())
            {
                var UserData = from ANU in db.AspNetUsers
                               where ANU.UserName == model.UserName
                               select new
                               {
                                   ANU.isAuthorized,
                                   ANU.isActive
                               };
    
                foreach (var c in UserData)
                {
                    //If User is NOT Authorized to log in
                    if (!Convert.ToBoolean(c.isAuthorized))
                    {
                        ModelState.AddModelError("", "This User is not Authorized to Login.");
                        return View(model);
                    }
                    else
                    {
                        //If User is NOT Active
                        if (!Convert.ToBoolean(c.isActive))
                        {
                            ModelState.AddModelError("", "This User is not Active.");
                            return View(model);
                        }
                    }
                }
    
    
            }
    
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, change to shouldLockout: true
            var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: true);
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                //case SignInStatus.UnAuthorized:
                //    return View("UnAuthorized");
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                case SignInStatus.Failure:
                default:
                     //Incorrect password or user does not exist
                    ModelState.AddModelError("", "Invalid login attempt.");
                    return View(model);
            }
        }