Asp.NET MVC cookie not persisting data when accessed remotely - c#

I have an issue with my asp.net MVC project, I am using cookies to persist user’s data
I use the following code to set cookie after successful login:
[HttpPost]
public ActionResult Index(string username,string password)
{
User user = db.Users.Where(t => t.username == username && t.password == password).SingleOrDefault();
if (user != null)
{
HttpCookie aCookie = new HttpCookie("cookie");
aCookie.Values["username"] = username;
aCookie.Values["role"] = user.role.ToString();
aCookie.Values["UserID"] = user.UserID.ToString();
aCookie.Values["route"] = "AdminReports";
aCookie.Secure = false;
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
isLogedIn = true;
return RedirectToAction("AdminReports", "Home");
}
TempData["ErrorMessage"] = "Wrong username or password!";
return View();
}
I Read the cookie using this code :
public ActionResult AdminReports()
{
Response.Write(Server.HtmlEncode(Request.Cookies["cookie"]["username"]));
// Response.Write(Request.Cookies["cookie"]["username"]);
if (Request.Cookies["cookie"] != null)
{
if (Convert.ToInt32(Request.Cookies["cookie"]["role"]) == (int)Enums.Role.Admin)
{
return View();
}
else if (Convert.ToInt32(Request.Cookies["cookie"]["role"]) == (int)Enums.Role.The70Hospitals)
{
return View("The70Hospitals");
}
else if (Convert.ToInt32(Request.Cookies["cookie"]["role"]) == (int)Enums.Role.The380Hospitals)
{
return View("The380Hospitals");
}
else
{
return View("LoginView");
}
}
else
{
return View("LoginView");
}
}
However the cookies lose its data which prevent the user to login. This case happens when I access the project remotely. However it works fine locally in the development mode and it runs normally also when I browse from the IIS (Run locally in the server)

Check your web.config file,
You can do some cookies settings in <system.web> section
<httpCookies domain="" httpOnlyCookies="true|false" requireSSL="true|false" />
use the System.Web.HttpCookie.HttpOnly property
Hope this helps.

Related

asp.net mvc multitenant database per login error

I'm building an app for our company which needs to have separate database per client. App is for the usage of other multiple companies, so the app needs to identify the company name when the user logs in and make the users operate only within their company db. I have it all set, but the problem is that the app is not able to handle many different databases simultaneously. When users from more different companies log in, the first users db gets changed to the db of the second user who is logged in! This is of course unacceptable. How can I make the app to use many dbs simultaneously?
I have one database which collects all app users and their company names and separate databases for each company. I also have a standard asp below are my codes:
My applicatinon dbcontext is
public static string _DbName;
public ApplicationDbContext() : base(string.IsNullOrWhiteSpace(ConString.dbCatlogConn) ? "DefaultConnection" : ConString.dbCatlogConn, throwIfV1Schema: false)
{
this.Database.CommandTimeout = 600;
}
public ApplicationDbContext(string dbName) : base(dbName)
{
_DbName = dbName;
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
Login class and database initializer in account controller
if (!ModelState.IsValid)
{
return View(model);
}
var regx = new Regex("[-]");
if (!regx.IsMatch(userdash))
{
ViewBag.Message = "Error";
return View();
}
string x = model.UserName.ToLower();
Session["Initial"] = x.Split('-').First();
var dbcompanies = db.CompanyLists.Where(t => (t.InitializationLetters == Session["Initial"].ToString())).Select(t => new { ConnString = t.ConnectionString }).ToList();
if (dbcompanies.Count > 0)
{
if (dbcompanies[0].ConnString == "")
{
}
else
{
Session["ConnectionString"] = dbcompanies[0].ConnString;
}
}
else
{
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "text here");
return View(model);
}
if (Session["ConnectionString"].ToString() == "" || Session["ConnectionString"].ToString() == null)
{
ViewBag.Message1 = "notfound";
return View();
}
else
{
using ( db = new ApplicationDbContext(Session["ConnectionString"].ToString()))
{
UserManager.PasswordHasher = new CustomPasswordHasher();
var user = db.Users.Where(e => e.UserName.ToLower() == model.UserName.ToLower()).FirstOrDefault();
var result = new SignInStatus();
if (user == null)
{
result = SignInStatus.Failure;
}
else
{
string dbPassword = dal.DecryptPassword(user.AnotherUsername, user.AnotherSalt, user.PasswordHash);
var status = UserManager.PasswordHasher.VerifyHashedPassword(dbPassword, model.Password);
if (status == PasswordVerificationResult.Success)
{
result = await SignInManager.PasswordSignInAsync(model.UserName, user.PasswordHash, model.RememberMe, shouldLockout: false);
}
else
result = SignInStatus.Failure;
}
switch (result)
{
case SignInStatus.Success:
if (user != null)
{
if (user.Disabled == true)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
ModelState.AddModelError("", language == "en" ? "Invalid login attempt." : "text");
return View(model);
//return View("Lockout");
}
else
{
var ip = Request.ServerVariables["REMOTE_ADDR"];
user.LastIpAddress = ip;
db.SaveChanges();
if (User.IsInRole(UsersTypes.Interview.ToString()))
{
return RedirectToRoute("profile", new { type = profile.Acceptance });
}
}
}
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("", language == "en" ? "Invalid login attempt." : "error");
return View(model);
}
}
}
I have found the same problem here asp.net mvc multitenant database per tenant
when I run i got error DbName cant to be null where should I declare or pass the database connection for that variable and will it be the main database?
I have also used the string literal as one of the comments like this one
private const string DbName = "default app connection string";
but I got error It must be variable or indexer
can I find help for that problem

Use session state to redirect user to homepage if already logged in

I have a login page and and a accounts controller with Login action. When I log in I get redirected to home page(which is good) but after logging in if I re visit the login page it shows the login form again (although I am logged in).
I tried check for session state values but every time I try to use it I get null reference error.
public ActionResult Login(string name, string password, string hash)
{
if (!string.IsNullOrWhiteSpace(name))
{
var user = _model.tblUsers.FirstOrDefault(x => x.username == name);
if (user != null)
{
if (user.powerLevel == 0)
{
Session["IsAdmin"] = (user.password == password);
Session["IsAuthor"] = null;
Session["IsUser"] = null;
}
else if (user.powerLevel == 1)
{
Session["IsAdmin"] = null;
Session["IsAuthor"] = (user.password == password);
Session["IsUser"] = null;
}
else if (user.powerLevel == 2)
{
Session["IsAdmin"] = null;
Session["IsAuthor"] = null;
Session["IsUser"] = (user.password == password);
}
else
{
return View("Login");
}
return RedirectToAction("Index","Posts");
}
}
return View("Login");
}
so if either of IsAdmin, IsAuthor, IsUser Session is set to true I want to get redirected to homepage. I tried check it with string.IsNullOrWhiteSpace but it doesnt work I always get false even if the Session is set to true

Authorize issue in MVC - database used flat file

I am new to MVC. I am facing below problem.
I wrote all logic in model.In Web.config I mention path of file (No Connection string).
I am adding [Authorize] attribute. After login, it is navigating to Home page. When I navigate gift create page again redirect to login page (Recursive).
FYI: Temporarily I am using session variable to solve problem.
This is my code
[HttpPost]
[ActionName("Create")]
[Authorize]
public ActionResult CreateGift(GiftModel gif)
{
if (Session["UserType"] != null)
{
if (Session["UserType"].ToString() == "1")
return RedirectToAction("Index", "home");
}
else
{
return RedirectToAction("Login", "User");
}
string path = System.Configuration.ConfigurationManager.AppSettings["Path"];
if (ModelState.IsValid)
{
Gift InsertCoupon = new Gift(path);
InsertCoupon.InsertGift(gif);
return RedirectToAction("GiftList");
}
return View();
}
In Web.config
<add key="Path" value="D:\"/>
Login Page
public ActionResult Login(LoginModel user)
{
string path = System.Configuration.ConfigurationManager.AppSettings["Path"];
if(ModelState.IsValid)
{
Users LoginUser = new Users(path);
UserModel uM = new UserModel();
uM.Password = user.Password;
uM.User_Email_ID = user.User_Email_ID;
uM.Name = user.Name;
string res = LoginUser.LoginUser(uM);
uM = LoginUser.GetUserFrom_Email(user.User_Email_ID);
if (res != "")
ViewBag.Msg = res;
else
{
Session["username"] = uM.Name;
Session["E_Mail"] = uM.User_Email_ID;
Session["UserType"] = uM.User_Type;
if (uM.User_Type == 0)
return RedirectToAction("AdminHome", "Admin");
else
return RedirectToAction("Index", "Home");
}
}
return View();
}

asp.net mvc 5 cookies not persisting on local server

Hi I am trying to set a cookie in my mvc5 application right after user logged in, and I am expecting cookie to persist after browser is closed, but requested cookie seems to be null after I closed the browser (it works fine when I try to access right after the login).
Here is how I created the cookie:
public ActionResult Login(User u)
{
// this action is for handle post (login)
if (ModelState.IsValid) // this is check validity
{
using (RoadTexEntities rte = new RoadTexEntities())
{
var v = rte.Users.Where(a => a.UserEmail.Equals(u.UserEmail) && a.password.Equals(u.password)).FirstOrDefault();
if (v != null)
{
var checkBox = Request.Form["rememberMe"];
if (checkBox == "on")
{
string user = JsonConvert.SerializeObject(v);
HttpCookie userCookie = new HttpCookie("user");
userCookie.Values.Add("details", user);
userCookie.Expires.AddDays(1);
Response.Cookies.Add(userCookie);
}
Session["username"] = v.UserFirst;
return RedirectToAction("AfterLogin");
}
else
{
ViewBag.Message = "Invalid Login Credentials";
}
}
}
return View(u);
}
public ActionResult Index(){
HttpCookie userCookie = Request.Cookies["user"];
if (userCookie != null)
{
return RedirectToAction("AfterLogin");
}
else
{
return RedirectToAction("Login");
}
}
I already checked the similar questions and checked my browser settings, but still I am getting null when I requested the cookie.
Change it to
userCookie.Expires = DateTime.Now.AddDays(1);
because your former code would not set the expire time of the cookie.

Forget password form in asp.net mvc 4

I try to implement forget password form in my asp.net mvc 4 project, everything works fine, but when I try to login to system with new password it told me that I have wrong password.
[HttpPost]
public ActionResult ForgetPassword(UserViewModel userModel) {
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
User user = _userRepo.GetUserByEmail(userModel.Email);
if (user == null) {
ViewBag.Error = Resources.Account.userEmailNotExist;
return View(userModel);
}
String newHashedPassword = Crypto.HashPassword(result);
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
_userRepo.SaveChanges();
string enMessage = "Your new password: " + result;
var httpCookie = Request.Cookies["lang"];
if (httpCookie != null && httpCookie.Value == "en") {
_mailHelper.SendEmail(userModel.Email, "New password", enMessage);
}
return RedirectToAction("ConfirmPasswordChange", "Account");
}
Login form:
[HttpPost]
public ActionResult Login(UserViewModel user) {
var users = _userRepo.GetAllEntitiesWithParam("JobsDb_Users_GetByEmail", user.Email).FirstOrDefault();
...
try {
var tryLogin = WebSecurity.Login(users.Username, user.Password, true);
if (tryLogin == WebSecurity.MembershipLoginStatus.Failure)
{
var httpCookie = Request.Cookies["lang"];
if (httpCookie != null && httpCookie.Value == "en") {
ViewBag.Error = "Your password is incorrect.";
new SeoHelper().ReturnSeoTags(this, "Login");
}
return View(user);
}
...
} catch {
...
}
}
inside WebSecurity
public static MembershipLoginStatus Login(string username, string password, bool rememberMe) {
if (Membership.ValidateUser(username, password)) {
FormsAuthentication.SetAuthCookie(username, rememberMe);
return MembershipLoginStatus.Success;
} else {
return MembershipLoginStatus.Failure;
}
}
inside Membership
public override bool ValidateUser(string username, string password) {
if (string.IsNullOrEmpty(username)) {
return false;
}
if (string.IsNullOrEmpty(password)) {
return false;
}
User user = _userRepository.GetAll().FirstOrDefault(usr => usr.Username == username);
if (user == null) {
return false;
}
if (!user.IsApproved.Value) {
return false;
}
if (user.IsLockedOut.Value) {
return false;
}
String hashedPassword = user.Password;
Boolean verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, password));
if (verificationSucceeded) { //here is I have false if try to login using password from forget form
user.PasswordFailuresSinceLastSuccess = 0;
user.LastLoginDate = DateTime.UtcNow;
user.LastActivityDate = DateTime.UtcNow;
} else {
int failures = user.PasswordFailuresSinceLastSuccess.Value;
if (failures < MaxInvalidPasswordAttempts) {
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
} else if (failures >= MaxInvalidPasswordAttempts) {
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.IsLockedOut = true;
}
}
_userRepository.SaveChanges();
if (verificationSucceeded) {
return true;
}
return false;
}
First step is to open up your database and verify that the new password was actually persisted. If it has, the most likely cause is that your repository is working with stale (cached) data.
If you're using Entity Framework, this happens because the framework will, by default, cache the state of the database at the time the DbContext is created, so it is retaining your original password. You can verify this by logging in with the original password.
I am not sure but following code does not look right to me:
User user = _userRepo.GetUserByEmail(userModel.Email);
if (user == null) {
ViewBag.Error = Resources.Account.userEmailNotExist;
return View(userModel);
}
String newHashedPassword = Crypto.HashPassword(result);
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
_userRepo.SaveChanges();
You fetched the user from repository, make changes to user object in memory and then called SaveChanges() on the repository. Does that work in your world? How does _userRepo.SaveChanges(); knows which object has changed. Do you see correct hashed value in DB after the call? What value you see in ValidateUser() method for password? Is the hashing algorithm consistent both while generating hashed password and while verifying?
I could be wrong, if that's the case it will be good if you share little bit more of analysis around the question I asked above.

Categories

Resources