mvc 5 Set Cookie Expire, but expiration back to 01/01/0001 - asp.net-mvc

I set cookie when login success like this :
public JsonResult LoginWithPassword(String password)
{
Response.Cookies.Remove("Auth");
string CookieName = "Auth";
long UserId = 4;
HttpCookie myCookie = HttpContext.Response.Cookies[CookieName] ?? new HttpCookie(CookieName);
myCookie.Values["UserId"] = UserId.ToString();
myCookie.Values["LastVisit"] = DateTime.Now.ToString();
myCookie.Expires = DateTime.Now.AddDays(1);
HttpContext.Response.Cookies.Add(myCookie);
return Json(new { IsSuccess = true, ReturnUrl = returnUrl });
}
else
{
return Json(new { IsSuccess = false, Message = "Login fail, Wrong Password" });
}
}
and i read it in next page/action :
public ActionResult Index()
{
if (HttpContext.Request.Cookies["Auth"] == null)
return RedirectToAction("Login", "Access");
return View();
}
Really strange the cookie of "Auth" always empty. When i check the expiration date in debugging breakpoint, i get expiration date : 01/01/0001.
why this happend and how to solve this?
This action in two differents controller

I have tried to implement your code to create cookie. Same code is working fine in MVC5 at my end in firefox browser.
I have used code as below to create cookie -
Response.Cookies.Remove("Auth");
string CookieName = "Auth";
HttpCookie cookie = HttpContext.Response.Cookies[CookieName] ?? new HttpCookie(CookieName);
//HttpCookie cookie = new HttpCookie("Cookie");
cookie.Value = "Hello Cookie! CreatedOn: " + DateTime.Now.ToShortTimeString();
cookie.Expires = DateTime.Now.AddDays(5);
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
In addition the check on "Auth" cookie is successful on Index page as -
public ActionResult Index()
{
if (HttpContext.Request.Cookies["Cookie"] == null)
return RedirectToAction("Login", "Account");
return View();
}
Alternatively I suggest to
1) Set Expiry after cookie is created in login page OR
2) add decimal in expiry days eg. 1.0 or 5.0. See article at link -
http://forums.asp.net/t/1982279.aspx?MVC5+Application+Cookie+expires+when+session+ends
Let me know if this helps you.

Related

Windows Authentication Logout / SigninwithDifferent User

I am using windows authentication in ASP.NET MVC.
I want to Logout? So I researched and found the following
The code is based on decompiling the Microsoft.TeamFoundation.WebAccess which has the "Sign in as a different User" function.
public ActionResult LogOut()
{
HttpCookie cookie = Request.Cookies["TSWA-Last-User"];
if(User.Identity.IsAuthenticated == false || cookie == null || StringComparer.OrdinalIgnoreCase.Equals(User.Identity.Name, cookie.Value))
{
string name = string.Empty;
if(Request.IsAuthenticated)
{
name = User.Identity.Name;
}
cookie = new HttpCookie("TSWA-Last-User", name);
Response.Cookies.Set(cookie);
Response.AppendHeader("Connection", "close");
Response.StatusCode = 0x191;
Response.Clear();
//should probably do a redirect here to the unauthorized/failed login page
//if you know how to do this, please tap it on the comments below
Response.Write("Unauthorized. Reload the page to try again...");
Response.End();
return RedirectToAction("Index");
}
cookie = new HttpCookie("TSWA-Last-User", string.Empty)
{
Expires = DateTime.Now.AddYears(-5)
};
Response.Cookies.Set(cookie);
return RedirectToAction("Index");
}
Is the above code reliable?
ANd how to redirect to another page like logout succesful
after response.clear??

Asp.net Identity - token is not matching encoding issue?

I am trying to use asp.net identity for authentication, I am having some issues with encoding/decoding.
User clicks on forgot password link, so we call out:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[PassModelStateToTempData]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
logger.Info("reset_password attempting for {0}", model.Email);
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
this.Flash("Please check your email, we have sent you instructions on how to reset your password");
return RedirectToAction("ForgotPassword");
}
string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
logger.Debug("forgot_password code {0}", code);
var callbackUrl = Url.Action("ResetPassword", "Session", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
messagingService.ResetPassword(user.Email, callbackUrl);
this.Flash("Please check your email, we have sent you instructions on how to reset your password");
logger.Debug("remind_me successfully send out email to {0} {1}", model.Email, callbackUrl);
return RedirectToAction("ForgotPassword");
}
logger.Info("reset_password failed for {0}", model.Email);
// If we got this far, something failed, redisplay form
return RedirectToAction("ForgotPassword");
}
User gets email then clicks link so we run:
[HttpGet]
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
if (code == null)
{
this.Flash("Invalid login token, please enter your email address again");
return RedirectToAction("ForgotPassword");
}
var vm = new ResetPasswordViewModel
{
Code = code
};
return View(vm);
}
We pass on token into view - we ask for email and password, then user hits post and we run:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return RedirectToAction("ResetPassword");
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
logger.Info("reset_password user not found [{0}]", model.Email);
// Don't reveal that the user does not exist
return RedirectToAction("ResetPasswordConfirmation", "Session");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Session");
}
AddErrors(result);
return RedirectToAction("ResetPassword", new { code = model.Code });
}
For some reason tokens seem to not match, here are an example of the token I am getting - why the case difference?
Token:
2015-10-14 13:06:52.7545|DEBUG|Controllers.Application|forgot_password code BoUZZ9OS7rEkKMkEJzerWdds4dZLHFTHO/EkjQC2Zr8YJvCyjsXUKBRLZk8jmAqhjyxOzgqOLdJ8P/ji8y+om2ne7bcsLICzcdLSHzrP6BNEr1/+HKvHcYan+JzAX7Ifpgq7casmMj4f9esAdxejLA==
Notice the case difference:
2015-10-14 13:07:29.7164|INFO|Controllers.Application|reset_password attempting for my.email#gmail.com with token: bouzz9os7rekkmkejzerwdds4dzlhftho/ekjqc2zr8yjvcyjsxukbrlzk8jmaqhjyxozgqoldj8p/ji8y+om2ne7bcsliczcdlshzrp6bner1/+hkvhcyan+jzax7ifpgq7casmmj4f9esadxejla== -> Invalid token.
Your MVC routing is set up to generate lowercase URLs:
routes.LowercaseUrls = true;
This means that your codes are also being converted to lowercase. Possible solutions are:
Turn off LowercaseUrls if you can (or want)
Use MVC attribute routing, though this can be quite a switch.
The simplest option for you may be to simply create the URL yourself:
//Generate the URL without the code parameter
var callbackUrl = Url.Action(
"ResetPassword",
"Session",
new { userId = user.Id },
protocol: Request.Url.Scheme);
//Manually add the code, remembering to encode it
callbackUrl = callbackUrl + "&code=" HttpUtility.UrlEncode(code);

Unable to Logout Completely From Web site Using Form Authentication

I am using form authentication to authenticate and authorize the request in my website.
Here is the code for Login :
var objLogin = new LoginModel { Email = model.Email, Password = CommonMethod.Encryptdata(model.Password) };
var UserDetail = Users.LoginUser(objLogin);
if (UserDetail.ErrorMessage == "SuccessLogin")
{
var UserData = UserDetail.UserId + "," + UserDetail.UserRole + "," + UserDetail.Email + "," + UserDetail.FirstName + "," + UserDetail.LastName;
DateTime expirydate = DateTime.Now.AddDays(10);
var Ticket = new FormsAuthenticationTicket(1, UserDetail.Email, DateTime.Now, expirydate, true, UserData, FormsAuthentication.FormsCookieName);
string hashCookies = FormsAuthentication.Encrypt(Ticket);
var Cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashCookies);
Response.Cookies.Add(Cookie);
ViewBag.InActiveStatus = "";
//Code for expiration
if (Ticket.IsPersistent)
{
Cookie.Expires = Ticket.Expiration;
}
if (!string.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
}
I am using persistent cookie.
The method used to logout of the website contains following code:
FormsAuthentication.SignOut();
Session.Abandon();
Session.Clear();
Session.RemoveAll();
string[] myCookies = Request.Cookies.AllKeys;
foreach (string cookie in myCookies)
{
Response.Cookies[cookie].Expires = DateTime.Now.AddYears(-1);
}
return RedirectToAction("Login", "Account");
The Problem I am facing is after sign out I am able to surf Home controller
Pages. I have implemented Authorize(Roles="user") on all home controller methods.
[Authorize(Roles = "user")]
public ActionResult Index()
But I am not able to surf pages from other controllers(other than home).e.g
In Challenge Controller the following method :
[Authorize(Roles = "user")]
public ActionResult MyChallenges()
The problem gets solved when I forcefully clean the browsers cookies.But this is not recommended for the normal user from user experience point of view.
Please tell why this is happening ? Thanks in Advance !
Hi Stackoverflow Experts
I am still waiting for my answer !
Thanks
Imastu

Redirect to actionmethod/view

I have implemented idel time out functionality. Here when the user is idel for 1 min, we redirect the user to login page. We have kept the track of the url that the user was when the auto logout happened. Eg , of the user is on reset password view and if the auto logout happens the url which i get is as follows
http://localhost/XYZ.Portal/?returnUrl=%2FXYZ.Portal%2FUser%2FResetPassword
the above url is achieved by using the following code
'#Url.Action("Login", "User", new { returnUrl = HttpContext.Current.Request.RawUrl })'
Now when the user logs in again as he is redirected to login page, I am using the following code to redirect him back but the code doesnt seem to work. What am I doing wrong.?
[HttpPost]
public ActionResult Login(FormCollection formCollection)
{
if (ModelState.IsValid)
{
UserBE user = new UserBE();
user.Email = formCollection["Email"];
user.Password = formCollection["Password"];
user = UserBL.AuthenticateUser(user);
if (user.AuthenticUser)
{
if (Request.QueryString["returnUrl"] != null)
{
string returnUrl = Server.UrlDecode(Request.QueryString["returnUrl"]);
Redirect(returnUrl );
}
else
{
Session["Email"] = user.Email;
return RedirectToAction("DashBoard");
}
}
else
return View(user);
}
return View();
}
[HttpGet] login action method:
[HttpGet]
public ActionResult Login()
{
return View();
}
returnUrl I get as XYZ.Portal/User/ResetPassword
Thanks In advance.
You need to return the RedirectResult:
if (Request.QueryString["returnUrl"] != null)
{
string returnUrl = Server.UrlDecode(Request.QueryString["returnUrl"]);
return Redirect(returnUrl);
}
See RedirectResult
Not working. Now my URL becomes localhost/XYZ.Portal
In this case you can do 1 of 2 options:
1) Write:
string startReturnUrl = "http://www." + your returnUrl
or
2) split your returnUrl like:
string viewName = returnUrl.Split('/').Last();
But I think better change returnUrl to just only Name of View that you need

Set cookie value before view loaded in MVC?

I need to set a cookie value before my view called. otherwise I have to refresh the page to get cookie value in the view. The problem here is the value of cookie will get in controller.
[HttpGet]
[Route("Abstract/{meetingCode}")]
[AllowAnonymous]
public ActionResult Index(string meetingCode)
{
var meetingAbstract = new MeetingAbstract();
meetingAbstract.Meeting = _abstractContext.GetMeetingWithMeetingCode(meetingCode);
if (meetingAbstract.Meeting != null)
{
var cookie = new HttpCookie("_culture");
cookie.Value = meetingAbstract.Meeting.language.language_locale_code;//"en-US";
cookie.Expires = DateTime.Now.AddDays(365);
cookie.Path = "/";
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
...
Any other way without refresh the page again to set cookie value?
Cookies have some peculiar behaviour, I mean you create them in the Response stream, to be sent to the client, but they are not available in the Request stream until they are sent from the client.
I mean, you cannot access the cookie unless it is being sent from the client.
Anyway, why you need to refresh your page to access the cookie you just created? Is not easier to use the same variable?
[HttpGet]
[Route("Abstract/{meetingCode}")]
[AllowAnonymous]
public ActionResult Index(string meetingCode)
{
var meetingAbstract = new MeetingAbstract();
meetingAbstract.Meeting = _abstractContext.GetMeetingWithMeetingCode(meetingCode);
var cookie;
if (meetingAbstract.Meeting != null)
{
cookie = new HttpCookie("_culture");
cookie.Value = meetingAbstract.Meeting.language.language_locale_code;//"en-US";
cookie.Expires = DateTime.Now.AddDays(365);
cookie.Path = "/";
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
} else {
cookie = this.ControllerContext.HttpContext.Request.Cookies["_culture"];
}
...

Resources