I have a cookie which is set when a user accesses the page /auth/ of my MVC3 application.
When a user posts the form data back to the server I modify the cookie by changing the value it has assigned. I then use Response.Cookies.Set(mycookie); to change the cookie to the value of mycookie.
The issue I am having is that when the page is first loaded 'get' request the cookie appears as a cookie. Upon receiving the post response back the cookie now appears as a session with a completely different expiry date.
CODE::
[HttpGet]
public ActionResult Auth()
{
var cookie = Request.Cookies.Get(login_cookie);
if (cookie == null || string.IsNullOrEmpty(cookie.Value))
{
Response.Cookies.Add(new HttpCookie(login_cookie) { Expires = DateTime.Now.AddMinutes(5), Value = "0", HttpOnly = true, });
}
.....
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(Login loginform)
{
int attempts = 0;
HttpCookie login_cookie_data = Request.Cookies.Get(login_cookie);
....
Response.Cookies.Set(login_cookie_data);
return View();
}
Resolved
Issues was with machine. I restart and it sorted all issues.
Add the root path when creating your cookie in the cookie constructor.
... new HttpCookie(login_cookie) { Path = "/", ...
Related
I can't figure out how to add the functionality of "Remember me" while logging in the website ASP.NET CORE 3.1 MVC according to the code I have below. Where and how should I check if the session on server side has expired and, in this case, load the user info from the DB according to the cookie?
Practical example: A user logs in (with "Remember me" checked) and comes back on the website 1 week later. In the meantime, the session on the server has expired. I would like the user to be automatically logged in when the user comes back.
Code executed server side when logging with "Remember me" checked:
var userClaims = new List<Claim>()
{
new Claim("id", user.Id.ToString()),
new Claim("id_organisation", user.Id_organisation.ToString())
};
var grantMyIdentity = new ClaimsIdentity(userClaims, "User Identity");
var userPrincipal = new ClaimsPrincipal(new[] { grantMyIdentity });
await HttpContext.SignInAsync(userPrincipal, new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddMonths(1)
});
In the Startup.cs I have:
public void ConfigureServices(IServiceCollection services)
{
...
TimeSpan expiration_cookie_and_session = TimeSpan.FromHours(2);
services.AddAuthentication("CookieAuthentication")
.AddCookie("CookieAuthentication", config =>
{
config.Cookie.Name = "UserLoginCookie";
config.LoginPath = "/connexion";
config.SlidingExpiration = true;
config.ExpireTimeSpan = expiration_cookie_and_session;
config.EventsType = typeof(MyCookieAuthenticationEvents);
});
services.AddScoped<MyCookieAuthenticationEvents>();
services.AddSession(options => {
options.IdleTimeout = expiration_cookie_and_session;
});
...
}
public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
{
//We are here in case of cookie expiration
public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> redirectContext)
{
...
}
}
My guess would be in the CookieAuthenticationEvents.OnSigningIn event. Can you help me to make it clear?
Thank you!!
You could get the cookie expire time by using:context.Properties.ExpiresUtc.
If you want to get the expire time in the other request after login successfully,you could add the expire time to HttpContext in ValidatePrincipal method.Once you sign in successfully and get into another action,it will hit the ValidatePrincipal method to add the expire time to HttpContext.
Custom CookieAuthenticationEvents:
public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
{
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
context.Request.HttpContext.Items.Add("ExpiresUTC", context.Properties.ExpiresUtc);
}
}
Get the expire time in the action:
public async Task<IActionResult> Index()
{
var expiretime = HttpContext.Items["ExpiresUTC"];
return View();
}
Result:
Update:
For how to judge the cookie expired:
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
context.Request.HttpContext.Items.Add("ExpiresUTC", context.Properties.ExpiresUtc);
//Compare() method Return value Meaning
//Less than zero means first is earlier than second.
//Zero means first is equal to second.
//Greater than zero means first is later than second.
var calculte = DateTimeOffset.Compare((DateTimeOffset)context.Properties.ExpiresUtc, DateTimeOffset.Now);
if(calculte<0)
{
// the cookie has been expired
//do your stuff...
}
}
I have an asp.net core 2.1 project and I try to use TempData with RedirectToAction but it's always null (without Error)
Here is my ConfigureServices method
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//services pour l'authentification
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = "/Login";
});
//services pour session
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(20);
});
//configuer port https
services.AddHttpsRedirection(options => options.HttpsPort = 443);
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
ManageDI(services);
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddSessionStateTempDataProvider();
}
I have "app.UseSession();" in my Configure method
and here is my code
[HttpGet]
public async Task< IActionResult> ResetPassword(string query)
{
TempData["test"]= "test";
return RedirectToAction(nameof(Login));
}
[HttpGet]
public IActionResult Login(string returnUrl = null)
{
var b = TempData["test"];
//b is always null when calling ResetPassword action
var model = new Models.Account.LoginModel{
ReturnUrl = returnUrl
};
return View(model);
}
What did I forget please ?
Thanks
It's not entirely clear what the issue is based on the code you've provided, but since you mention that it's null in your ResetPassword action from within your Login action, I'm assuming you're not properly persisting the value.
TempData is just that: temporary data. Once it's been accessed, it is removed. Therefore, when you set b here with its value, that's it - it's gone. If you then try to access it in another action later or even just in the view this action returns, it will be null now.
If you need to get the value, but also keep it around for later, you need to use TempData.Peek:
var b = TempData.Peek("test");
I'm working on a spring web project and created HttpSession for validating login and access of jsp pages. I haven't used the standard spring technique of security. However i'm setting the session on the time of login and matching this session on each webService call.
Now on Logout i want to redirest the user on login screen and destroy the session so that nothing can be accessible without relogin. I don't know how to destroy the session.
// Here is code of setting the session
StaffModel record1 = (StaffModel) data.get("records"); // separating records
if(record1 != null)
{
SessionData sessionData = new SessionData();
sessionData.setMobileNo(record1.getMobileNo());
sessionData.setCityName(record1.getCity());
sessionData.setUserName(record1.getFirstName());
sessionData.setUserRole(record1.getRole());
sessionData.setSessionID(UUID.randomUUID());
sessionObj.setAttribute("SessionData" , sessionData); // setting session Data
}
// in jsp i'm accessing these sessions
<script>
var sessionData;
var sUserName;
var sMobileNo;
var sUserRole;
var sCityName;
var sSessionId;
function sessionCall()
{
sUserName = '<% SessionData obj = (SessionData)session.getAttribute("SessionData");
out.print(obj.getUserName());
%>';
sMobileNo = <% out.print(obj.getMobileNo()); %>;
sUserRole = '<% out.print(obj.getUserRole()); %>';
sSessionId = '<% out.print(obj.getSessionID()); %>'
sCityName = '<% out.print(obj.getCityName()); %>';
sessionData =
{
"mobileNo" : sMobileNo,
"cityName" : sCityName,
"userName" : sUserName,
"userRole" : sUserRole,
"sessionID": sSessionId
};
document.getElementById("staffName").innerHTML=sUserName;
document.getElementById("staffRole").innerHTML=sUserRole;
}
</script>
Problem : on click of logout button destroy the HttpSession
Help Please
// Do this on your controller
#RequestMapping(value = "/logout")
public String logout(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
return "redirect:/"; //Where you go after logout here.
}
// do this on your jsp page
Logout
You can always add HttpSession session as a parameter in a Controller method. Do it and try:
session.invalidate();
P.S.: Seems like using Spring Security would be way easier for you, you should think about changing your configuration.
I have a Logout action on a controller as so:
public ActionResult Logout()
{
FormsAuthentication.SignOut();
Session["UserCredential"] = null;
return RedirectToAction("Index", "Home");
}
This working in google chrome browser. but when I am using my web application with firefox browser (latest version) after login and logout from first time. and when I am doing login again to application and pressing on logout button, I am not able to logout from web application. Request.IsAuthenticated is returning me true value.
For Login I used following action:
[HttpPost]
public JsonResult Login(string userName, string password)
{
User oUser = oRepository.GetUser(userName,password);
Session["UserCredential"] = oUser;
if (oUser != null)
{
if (oUser.IsVerified)
{
string url = Request.Url.AbsolutePath;
FormsAuthentication.SetAuthCookie(userName, false);
return Json(new { res = 1, RedirectUrl = Url.Action("Index", "Home") }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { res = 0, RedirectUrl = "" }, JsonRequestBehavior.AllowGet);
}
}
return Json(new { res = -1, RedirectUrl = "" }, JsonRequestBehavior.AllowGet);
}
Anyone have idea what i have to do to solve my problem with firefox browser.
I am not 100% certain but you could try this.
I've observed that the way FormsAuthentication is implemented in ASP.NET, the SignOut method does not clear the ASPXAUTH cookie. So, on sign-out, what I usually do is, I clear all the cookies in the response myself manually.
You might try doing that. At the very least, in your case, you should clear 2 cookies:
1) The FormsAuth cookie. You can get the name of the cookie by accessing a CookieName (or some such) static field of the FormsAuthentication class.
2) The ASP.NET session cookie. Check the cookie names in the Immediate Window (print the Cookies collection).
To clear the cookies, just add new cookies to the response object's cookie collection with the same names as the older cookies and then set their expiry date to a date in the past.
I am using the SessionExpireFilter on each action to check if session has expired or not. If session has expired then it redirects the user to sessionTimeoutPage i.e. to membershipController and SessionTimeOut View
The filter looks like-
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
/// <summary>
/// Called when [action executing].
/// </summary>
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
// check if session is supported
if (ctx.Session != null)
{
// check if a new session id was generated
if (ctx.Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
if (ctx.Request.IsAuthenticated)
{
FormsAuthentication.SignOut();
}
//HttpCookie mycookie = new HttpCookie("ASP.NET_SessionId");
//mycookie.Expires = DateTime.MinValue;
//ctx.Response.Cookies.Add(mycookie);
//ctx.Session.Clear();
RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
redirectTargetDictionary.Add("action", "SessionTimeOut");
redirectTargetDictionary.Add("controller", "Membership");
filterContext.Result = new RedirectToRouteResult(redirectTargetDictionary);
}
}
}
base.OnActionExecuting(filterContext);
}
}
The problem is I have a Membership controller login action method which also has that filter. It checks for the session expire and always find the ASP.NET_SessionId cookie and redirects to sessionTimeout page(Which has a link to login page) again and again
It would be great of somebody can help.
For this solution to work, you need to wireup the Session_Start event in Global.asax. If you wont do it, the Session.IsNewSession will always be true (that's the way the ASP.NET runtime works). Sometimes it is also necessary to store something (anything) in the Session.