Disable Cookieless Session .Net MVC 5 - c#

We previously had cookieless session enabled on our application. We have disabled this and gone to session cookies however we are having a problem. Users who had the session ID in their URL as a bookmark are still able to navigate to the site with the session id in the url. I have set it to not regenerate expired sessions but it is still allowing it anyways. It also ends up creating a session cookie in addition and then we are getting random session loss. I've come up with a few wonky workarounds like stripping it out using a URL rewrite and stripping it out via javascript but this seems bad. Is there anything built in that I am missing that can help with this? Not that it should matter for this but I will add we are using state server.

For anyone else looking for a solution that won't require users to update their bookmarks I was able to use the following in my Global.asax Application_BeginRequest:
void Application_BeginRequest(object sender, EventArgs e) {
if (CookielessValuesExist()) {
Response.Redirect(Request.Url.OriginalString, true);
}
}
private bool CookielessValuesExist() {
string cookieless = Request.Params["HTTP_ASPFILTERSESSIONID"];
if (string.IsNullOrWhiteSpace(cookieless)) {
return false;
}
return true;
}

A URL rewrite is a good solution to this.
However if you would like users to update their bookmarks, (so you can eventually retire the URL rewrite) you might consider having your URL rewrite send them to a page telling them so:
Oops! That link doesn't work.
And then giving them the usual options to log in etc.

Related

MVC 4 Lose Session Because Redirects From www.website.com to website.com

I just realize that session is lost when redirecting from www.website.com to website.com without www.
However I am quite lucky that I can set up the server so all redirection is start with www. In the future I do not want my application to be server dependent, I want to make it code dependent.
For example:
#Html.Hidden("PageManagerUrl", Url.Action("PageManager","Admin"))
produces /Admin/PageManager/, and I use location.href = url (when url is /Admin/PageManager/.
It is not 100% sure that I will lose my session at the first time of redirection, but when I tested it but redirecting back and forward, about the 3rd or 4th time, the session will be lost. After I set up the server setting to:
Preferred domain * www.website.com
Select the URL (either with or without the www. prefix) to which site visitors will be redirected via a SEO-safe HTTP 301 redirect.`
The session is never lost again. So I wonder, how to do the best redirection without losing my session? Please give me example how to do it from controllers and javascript / views.
Do you have any global.asax file ?
If yes, then please check whether it contains these two methods signature.
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}

How to redirect percentage of users to a beta test web site?

First of all, we are using MVC 3, ASP.NET 4.0 and Visual Studio 2010.
Our goal is to open up our brand new web site to an open beta. We want to redirect a slowly increasing percentage of our traffic to our new site while the rest of our traffic goes to our existing site...
We were hoping to do this via a load balancer, but this is no longer an option due to resources, infrastructure and time. Right now it seems our only option is to do it via software.
Has anyone here done this? Do you have a good strategy or solution?
We will have two different URLS and we can use cookies to achieve this if needed.
It's fairly simple and would be done the same way user's are redirected to mobile site.
Implement Application_PreRequestHandlerExecute in global.asax.cs
If they fit whatever criteria you decide, Response.Redirect them. I'd store a cookie on whomever is going to stay on one site or the next so they dont erroneously get redirected while in the middle of viewing the non-beta site. This also doesn't handle the case of people not using cookies.
This is pseudo code, so it may not be 100% correct
protected void Application_PreRequestHandlerExecute(object sender, EventArgs
e)
{
if(Request.Cookies["BetaResult"] == null)
{
var cookie = new HttpCookie("BetaResult");
cookie.Expires = DateTime.Now.AddDays(1d);
if(whatever logic to redirect to beta)
{
cookie["BetaResult"] = "Beta";
Response.Cookies.Add(cookie);
Response.Redirect("your beta site");
}
else
{
cookie["BetaResult"] = "Main";
Response.Cookies.Add(cookie);
}
}
else
{
//if cookie value is beta, redirect to beta site, they 'are a chosen one'
}
}

How can I handle forms authentication timeout exceptions in ASP.NET?

If the session has expired and the user clicks on a link to another webform, the asp.net authentication automatically redirect the user to the login page.
However, there are cases when the user does not click on links to other webforms. For example: edit link in gridviews, when using AutoCompleteExtender with textboxes and the application attempts to get the information, and basically, in every case when a postback is done and the event is not automatically handled by the asp.net authentication.
What is the best way to handle these exceptions?
UPDATE: I have just modified the question title: forms authentication timeout, instead of the initial session timeout. Thanks for making me aware of this difference.
UPDATE: I have just created a new question with the specific problem I am facing: How to handle exception due to expired authentication ticket using UpdatePanel?. Surprisingly, I have not found much information about it. I would really appreciate your help.
This is why many systems include timers on the page to give approximate timeout times. This is tough with interactive pages. You really need to hook ajax functions and look at the return status code, which is a bit difficult.
One alternative is to use code based on the following which runs early in the page lifecycle and perform an ajax redirect to a login page. Otherwise you are stuck trying to intercept the return code from ajax and in asp.net where the ajax is done 'for you' (ie not a more manual method like jQuery) you lose this ease of detection.
http://www.eggheadcafe.com/tutorials/aspnet/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspx
for a quick hack you can try it directly in pre_init
http://forums.asp.net/t/1193501.aspx
Edit
what is wanted are for forms auth timeouts, not session timeouts. Forms auth timeouts operate on a different scale than session timeouts. Session timeouts update with every request. Forms auth tickets aren't actually updated until half of the time goes by. So if you have timeouts set to an hour and send in one request 25 minutes into it, the session is reset to an hour timeout, the forms auth ticket isnt touched and expires in 35 minutes! To work around this, sync up the session timeout and the forms auth ticket. This way you can still just check session timeouts. If you don't like this then still - do the below and sync up the timeouts and then parse the auth ticket and read its timeout. You can do that using FormsAuthentication.Decrypt - see:
Read form authentication cookie from asp.net code behind
Note that this code requires that upon login you set some session value - in this case its "UniqueUserId". Also change the login page path below to fit yours.
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
//Only access session state if it is available
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
{
//If we are authenticated AND we dont have a session here.. redirect to login page.
HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authenticationCookie != null)
{
FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value);
if (!authenticationTicket.Expired)
{
if (Session["UniqueUserId"] == null)
{
//This means for some reason the session expired before the authentication ticket. Force a login.
FormsAuthentication.SignOut();
Response.Redirect("Login.aspx", true);
return;
}
}
}
}
}
If you're using Forms Authentication, the user will be redirected to the login page when the Forms Authentication ticket expires, which is not the same as the Session expiring.
You could consider increasing the Forms Authentication timeout if appropriate. Even to the extent of using a persistent cookie. But if it does expire, there's no real alternative to redirecting to the login page - anything else would be insecure.
One way to deal with Session timeouts is to use Session as a cache - and persist anything important to a backing store such as a database. Then check before accessing anything in Session and refresh if necessary:
MyType MyObject
{
get
{
MyType myObject = Session["MySessionKey"] as MyType
if (myObject == null)
{
myObject = ... get data from a backing store
Session["MySessionKey"] = myObject;
}
return myObject;
}
set
{
Session["MySessionKey"] = value;
... and persist it to backing store if appropriate
}
}
If you're using a master page or a base page, I would add some logic to one of the events in the page lifecycle to check whether the session is new:
protected void Page_Load(object sender, EventArgs e)
{
if (Session.IsNewSession)
{
//do whatever you need to do
}
}

How to Kill A Session or Session ID (ASP.NET/C#)

How can I destroy a session (Session["Name"]) when the user clicks the logout button?
I'm looking through the ASP.NET API Reference on MSDN and it doesn't seem to have much information. It seems rather limited. But I cannot find any other pages for ASP.NET Classes etc.
I have tried:
Session.Abandon(); and
Session.Contents.Remove("Name"); neither of them work. ( I found these in a forum from a Google search)
The Abandon method should work (MSDN):
Session.Abandon();
If you want to remove a specific item from the session use (MSDN):
Session.Remove("YourItem");
EDIT: If you just want to clear a value you can do:
Session["YourItem"] = null;
If you want to clear all keys do:
Session.Clear();
If none of these are working for you then something fishy is going on. I would check to see where you are assigning the value and verify that it is not getting reassigned after you clear the value.
Simple check do:
Session["YourKey"] = "Test"; // creates the key
Session.Remove("YourKey"); // removes the key
bool gone = (Session["YourKey"] == null); // tests that the remove worked
It is also a good idea to instruct the client browser to clear session id cookie value.
Session.Clear();
Session.Abandon();
Response.Cookies["ASP.NET_SessionId"].Value = string.Empty;
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-10);
Session.Abandon()
This marks the session as Abandoned, but the session won't actually be Abandoned at that moment, the request has to complete first.
From what I tested:
Session.Abandon(); // Does nothing
Session.Clear(); // Removes the data contained in the session
Example:
001: Session["test"] = "test";
002: Session.Abandon();
003: Print(Session["test"]); // Outputs: "test"
Session.Abandon does only set a boolean flag in the session-object to true. The calling web-server may react to that or not, but there is NO immediate action caused by ASP.
(I checked that myself with the .net-Reflector)
In fact, you can continue working with the old session, by hitting the browser's back button once, and continue browsing across the website normally.
So, to conclude this: Use Session.Clear() and save frustration.
Remark: I've tested this behaviour on the ASP.net development server. The actual IIS may behave differently.
Session.Abandon() this will destroy the data.
Note, this won't necessarily truly remove the session token from a user, and that same session token at a later point might get picked up and created as a new session with the same id because it's deemed to be fair game to be used.
You kill a session like this:
Session.Abandon()
If, however, you just want to empty the session, use:
Session.Clear()
Session.Abandon()
is what you should use. the thing is behind the scenes asp.net will destroy the session but immediately give the user a brand new session on the next page request. So if you're checking to see if the session is gone right after calling abandon it will look like it didn't work.
Session["YourItem"] = "";
Works great in .net razor web pages.
Session.Abandon(); did not work for me either.
The way I had to write it to get it to work was like this. Might work for you too.
HttpContext.Current.Session.Abandon();

ASP.NET MVC 2 caching problem

I'm writing an app and have come across caching problem which I cannot work out.
I have a default Home controller for the site which checks whether the user is authenticated or not.
If is not then LogOn View is displayed otherwise the client is redirected to another page.
Along with the LogOn view, also a Check cookie is being sent to user to check on response if his browser supports cookies or not.
When I delete the cookie before sending the form with credentials, Home (Post method) in Home controller displays message that cookies must be enabled with a button which
should refresh the page with Logon boxes(http://localhost:1234/)
This button is linked to js refresh function:
var sURL = unescape("/");
function refresh()
{
window.location.href = sURL;
}
I have implemented CacheFilter which is set on the base controller.
public class NoCache : ActionFilterAttribute, IActionFilter
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}
}
and the problem is that if I Immediately click the button to refresh LogOn page, browser read it using its cache. But when I do it after a few seconds then the query is sent to the server.
This is wrong, because LogOn page should also create again a Check cookie.
It seems to me that the cache policy is set to 1-2 seconds, and after this time pages are reloaded from the server.
What is wrong? Thanks for help.
I have seen some similar behaviour, related to the javascript in IE7. The browser 'helpfully' realizes that you've recently requested that URL and therefore serves up the cached version. If this is the case, the solution is to make sure the URL is unique every time by adding a pseudo random number. I use something like:
function refresh()
{
window.location.href = sURL + "?rnd="+ Math.random();
}
Am I right in saying you're testing this by running this in Visual Studio?
As far as I know you can't enable things like caching in the Visual Studio Development Server. This is something you will enable on your webserver, which I guess will be IIS in your case.

Categories