How to add remember me functionality in ASP.NET MVC? - asp.net

I have a login form like this :
[HttpPost]
public ActionResult Login(UserAccount user , [Bind(Include = "ID,NameOfSession")] SessionSave Sessions)
{
using (QuestionsDBContext db = new QuestionsDBContext())
{
var usr = db.userAccount.Single(u => u.UserName == user.UserName && u.Password == user.Password);
if (user != null)
{
Session["UserID"] = usr.UserID.ToString();
Session["Username"] = usr.UserName.ToString();
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "Username or Password is wrong");
}
}
return View();
}
It appears every time I want to go to the index view, as it is coded like this. I want to make it remember all time when I log in at once. I know, I can do it by many ways, but please inform me about possible ways and any further references, that can be useful.

Related

MVC custom login authentication

Hi I'm developing an app in MVC and I have a problem with login, I want to know how can I manage the login depending on the user role.
While the moment the login works fine but I need to identify the role user for sending to different pages
I have a table in my database call Employee and one column is call IdPosition that is referred to another table call Position.
Here is my code
[HttpPost]
public ActionResult Autorizacion(Pepitos.Models.Employee employee)
{
using (pepitosEntities db = new pepitosEntities())
{
var userDetails = db.Employees.Where(x => x.Username == employee.Username && x.Password == employee.Password).FirstOrDefault();
if (userDetails == null)
{
employee.ErrorLoginMensaje = "Username or Password incorrect";
return View("Login",employee);
}
else
{
Session["IdEmployee"] = userDetails .IdEmployee;
Session["name"] = userDetails.Name;
return RedirectToAction("EmployeesIndex", "EmployeesHome");
}
}
}
Now what you need to do is check the role after the username and password matches and then redirect accordingly.for that i assumed you have role column in your database table along with username and password.
using (pepitosEntities db = new pepitosEntities())
{
var userDetails = db.Employees.Where(x => x.Username == employee.Username && x.Password == employee.Password).FirstOrDefault();
if (userDetails == null)
{
employee.ErrorLoginMensaje = "Username or Password incorrect";
return View("Login",employee);
}
else
{
var userRole=userDetails.role; //get the role of the user i.e whether user is admin or any other role
if(userRole=="Admin")
{
Session["IdEmployee"] = userDetails .IdEmployee;
Session["name"] = userDetails.Name;
return RedirectToAction("EmployeesIndex","EmployeesHome");
}
else if(userRole=="User")
{
Session["IdUser"] = userDetails .IdUser;
Session["name"] = userDetails.Name;
return RedirectToAction("UserIndex","UserHome");
}
//and so on
}
}
hope it helps!

Cannot Get ID of user after login using User.Identity.GetUserId()

I am using Microsoft.AspNet.Identity in my application.
The user can Log In and can only see his/her own controller.
Because I've added attributes ([Authorize(Roles = "1")]) and this works fine as well.
But I can't get the user Id by using string users = User.Identity.GetUserId();.
users is always null, and I don't know why.
I am not using default login template.
And one more thing, after login I've done something like this
if (User.IsInRole("1"))
{
return RedirectToAction("Dashboard", "Supplier");
}
else if (User.IsInRole("2"))
{
return RedirectToAction("Dashboard", "Site");
}
but it does not work as well. But when I login and go to controller which has Authorize(Roles ="1") in controller, it does not give any error or redirect to login page.
But when I login with the user (which has Roles="2"), I cannot access the controller with Authorize(Roles="1").
This is how I have configured ASP.Net Identity:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
ExpireTimeSpan = TimeSpan.FromMinutes(5),
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login/Index") });
}
}
}
Update
For Redirection based on Role I've updated my Controller/Action.
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginView login)
{
if (ModelState.IsValid)
{
var user = (from u in db.logins
where u.user_name == login.user_name && u.user_password == login.user_password && u.isactive == 1
select new
{
u.user_name,
u.login_id,
u.user_type,
u.isactive
});
if (user.FirstOrDefault() != null)
{
FormsAuthentication.SetAuthCookie(login.user_name, true);
Session["UserName"] = user.FirstOrDefault().user_name;
string userId = User.Identity.GetUserId();
return RedirectToAction("RedirectToDefault");
}
else
{
ViewBag.error = "User Does Not Exist";
return View(login);
}
}
else
{
ModelState.AddModelError("", "Invalid Credentials");
}
return View(login);
}
And the in RedirectToDefault I've added:
public ActionResult RedirectToDefault()
{
String[] roles = Roles.GetRolesForUser();
string id = User.Identity.GetUserId(); //<- this is null here as well.
string name = User.Identity.GetUserName();
if (roles.Contains("1"))
{
return RedirectToAction("Index", "Supplier");
}
else if (roles.Contains("2"))
{
return RedirectToAction("Index", "Site");
}
and so on..
Any help would be much Appreciated.
From your incomplete code it looks like you are doing everything manually, selecting users from the db and so on.
Try using the SignInManager:
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginView login)
{
if (ModelState.IsValid)
{
var result = await SignInManager.PasswordSignInAsync(login.Username, login.Password, false, shouldLockout: true);
if (result == SignInStatus.Success)
{
//FormsAuthentication.SetAuthCookie(login.user_name, true);
//Session["UserName"] = user.FirstOrDefault().user_name;
//string userId = User.Identity.GetUserId();
//These shouldn't be neede anymore
return RedirectToAction("RedirectToDefault");
}
else
{
ViewBag.error = "User Does Not Exist";
return View(login);
}
}
else
{
ModelState.AddModelError("", "Invalid Credentials");
}
return View(login);
}
I would suggest that you read up on how Identity works, as it does everything for you, however you need to know how to access the data.
You can get user id through UserManager like:
var user = await UserManager.FindAsync(username, password);
Hope this helps someone.

Show error message for wrong password

I have this login code and I want to show (error message "Invalid User&Password") If someone input a wrong password, currently right now my code is just redirecting to same page if error occur.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Login l,string ReturnUrl="")
{
using (graceEntities dc = new graceEntities())
{
var user = dc.tbl_User.Where(a => a.UserName.Equals(l.Username) && a.Password.Equals(l.Password)).FirstOrDefault();
if (user != null)
{
FormsAuthentication.SetAuthCookie(user.UserName,l.RememberMe);
if (Url.IsLocalUrl(ReturnUrl))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index","Main");
}
}
}
ModelState.Remove("Pasword");
return View();
}
You need to handle the case where the user is not found in the database. Please read the comments inline in code below for further clarification:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Login model, string ReturnUrl = "")
{
// 1. Do validation and return view if validation errors
if (!ModelState.IsValid)
{
return View(model);
}
// 2. No validation error so search db for user
using (graceEntities dc = new graceEntities())
{
var user = dc.tbl_User
.Where(a => a.UserName.Equals(model.Username) &&
a.Password.Equals(model.Password)).FirstOrDefault();
if (user != null)
{
FormsAuthentication.SetAuthCookie(user.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl))
{
return Redirect(ReturnUrl);
}
// No return url, redirect to main/index
return RedirectToAction("Index", "Main");
}
}
// 3. We made it here, so user was not found
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}

The procedure does not work properly Entity Framework ASP.NET MVC 5 C#5

I have been facing this problem with assigning users to a proper role. The code looks just fine, but in reality half of the users gets a proper role, the other half stays without a role at all. Here is the method which does it:
public IdentityResult RefreshUserGroupRoles(long? userId)
{
if (userId == null) throw new ArgumentNullException(nameof(userId));
var user = _userManager.FindById(userId.Value);
if(user == null)
{
throw new ArgumentNullException(nameof(userId));
}
// Remove user from previous roles:
var oldUserRoles = _userManager.GetRoles(userId.Value);
if (oldUserRoles.Count > 0)
{
_userManager.RemoveFromRoles(userId.Value, oldUserRoles.ToArray());
}
// Find the roles this user is entitled to from group membership:
var newGroupRoles = this.GetUserGroupRoles(userId.Value);
// Get the damn role names:
var allRoles = _roleManager.Roles.ToList();
var addTheseRoles = allRoles.Where(r => newGroupRoles.Any(gr => gr.AppRoleId == r.Id));
var roleNames = addTheseRoles.Select(n => n.Name).ToArray();
//_db.Database.CurrentTransaction.Commit();
// Add the user to the proper roles
var transaction = _db.Database.BeginTransaction();
IdentityResult result;
try
{
result = _userManager.AddToRoles(userId.Value, roleNames);
transaction.Commit();
_db.DbContextTransactionAu.Commit(); //This is for Audit
}
catch (Exception)
{
transaction.Rollback();
throw;
}
_db.DbContextTransactionAuDispose?.Dispose();
return result;
}
public IEnumerable<AppGroupRole> GetUserGroupRoles(long userId)
{
var userGroups = this.GetUserGroups(userId).ToList();
if (userGroups.Count == 0) return new Collection<AppGroupRole>().AsEnumerable();
var userGroupRoles = new List<AppGroupRole>();
foreach(var group in userGroups)
{
userGroupRoles.AddRange(group.AppRoles.ToArray());
}
return userGroupRoles;
}
Any idea what could be wrong?

Working on Sign up page with ASP .net

I'm an intern developer and learning to code in ASP .net with mvc framework.
I'm working on a sign up page for a website where the users have to click on the link provided to validate their account with a website while registering their account.
Now, if the users have not clicked on the link which was sent to them in an email while registering then the user will not have a valid account and for those users I want that this message should be displayed "Please confirm your link to activate your account".
For that my code is as below but this code is giving me errors while I run it (looks like it is not going into the else condition.
My code is as below and is not working. Can someone please help me on this-
public ActionResult Login(LoginModel model, string returnUrl)
{
Session["CheckAmountOfSites"] = true;
ViewBag.SuggestBrowser = false;
if (ModelState.IsValid)
{
try
{
model.UserName = model.UserName.Trim().ToLower();
if (ValidateUser(model.UserName, model.Password))
{
if (activated == true)
{
FormsAuthentication.SetAuthCookie(model.UserName.ToLower(), model.RememberMe);
--Some more stuffs in if condition but have not been pasted completely here for --security reasons
} }
This is my else condition--But somehow its not entering the else part.
//validate user is not true
else
{
//ModelState.AddModelError("", "The Email or Password provided is incorrect.");
if (activated == false)
{
return RedirectToAction("Confirm", "Account", new { userName = model.UserName });
}
}
Confirm action--
[AllowAnonymous]
public ActionResult Confirm( string userName)
{
using (var db = SiteUtil.NewDb)
{
var user = db.Users.Where(n => n.Username == userName && n.CanLogin == false).FirstOrDefault();
if (user.CanLogin == false)
{
ViewBag.Email = "Please confirm your mail to activate your account";
}
}
return View();
}
public bool ValidateUser(string userName, string password)
{
using (var db = SiteUtil.NewDb)
{
var user = db.Users.Where(n => n.Username == userName && n.IsActive).FirstOrDefault();
if (user == null)
{
return false;
}
if (user.CanLogin == false)
{
//Mod("Email", "please confirm the mail which was sent to you");
//ViewBag.Email = "please confirm the mail which was sent to you";
return true;
}

Resources