For my application I want to clear the cache before logging.
However, if someone logs with different account, I want to clear the cache so that the page is refreshed and doesn't keep the previous user's values.
How do I do this in C#?
Create an if condition to check log in accounts. Then use the code in this reference to clear the cache if it satisfy the condition.
Using this Code you can clear the browser cache.
You can also use it on LogOut of your site instead of login.
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Or you can do this way
https://stackoverflow.com/a/2876701/2218635
You can define a cache by this way
HttpContextBase httpContext = filterContext.HttpContext;
httpContext.Response.AddCacheItemDependency("Pages");
and setup a cache when login
protected void Application_Start()
{
HttpRuntime.Cache.Insert("Pages", DateTime.Now);
}
and clear cache when logout
HttpRuntime.Cache.Insert("Pages", DateTime.Now);
more details
Clearing Page Cache in ASP.NET
You cannot write code to clear the client browser cache. All you can do it set control cache policy for data when you send the date to the browser in the first place.
E.g., if you initially have an image file, with expiration set to midnight when the browser retrieves it, the browser will not remove the file from its cache before midnight. If you need to immediate force the browser to fetch a different version of the file, the URI must change -- i.e., rename the file to a new (version 2) name.
You can only control cache policy of item sent to the browser (or the intervening proxy server, or both). The browser can ignore the policy (if it wants to be a really bad browser), but you CAN NOT send anything that will clear pre-existing browser cache.
Policy (in the http header), set things like expiration time (GMT), relative time (i.e., cache duraction), as well as no-cache directives. You can set this for the browser cache (or proxy and shared cache). But once it goes over the wire, you can not clear it.
ADDED
Took me a while to find this article explaining how browser caching works. Easier to understand than the W3C explanation of browser caching
Related
I'm working on a project with Asp.Net MVC 5 and Asp.Net Identity and I'm using two factor authentication. For the login I use:
var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
which is the default code that came with the new project. However, I also need the ability for a user to "trust" or "remember" a browser, similar to how banks can indicate if this was the first time you have signed in from a particular browser/pc.
My question is around the RememberBrowser property on the sign in method and what .NET Identity does with this data. I want the list of saved browsers and the ability to revoke access to one/and-or all of them. Is that possible within the Identity framework? Also, can I tell if a browser has been "trusted" before by some type of lookup?
Edit:
Maybe it's a good idea to save the browser info in the database and check on login instead of the cookie? That way it can be shown as a list with the ability to delete it. What I'm looking for is what to save and how to integrate it with the Asp.Net Identity without having a security risk.
Edit 2
Here's an example from a website that is already using this:
Edit 3
Maybe this can be implemented as another step for authentication. So basically we'll have a 3 factor authentication:
First user logs in with user/pass
Then we'll check if the 2FA is enabled and get the code if necessary
We get the user's aser agent and IP and check the database if it's new. Then notify if necessary.
So I'm guessing an new cookie should be added to save browser's info. However, we should be able to invalidate this cookie along with the 2FA cookie.
RememberBrowser sets a cookie that allows the 2FA step to be skipped. There is no central way to track this though it would be easy enough to log, however the results may not be accurate because people can delete cookies manually. There's no way to invalidate it I believe but it doesn't really matter as you can invalidate their session and the user is will be required to login with their password again.
Not sure whether saving browser info adds value as browser info is gonna be same for different users (using same browser and version) unless you save requestor IP as well; and saving requestor IP has too many complications.
How about adding a custom claim to the token if user has set RememberBrowser and then do your logic based on this custom claim? For eg, set a custom claim your_claim_name and set a Guid.NewGuid() to it if RememberBrowser is true. Also save the username, this guid and status flag in database . When a request comes, check whether your custom claim is present, if yes query the table with the custom claim value and username to check whether the entry is still active.
You can either delete the entry or soft delete (set the status) the entry for an user so that when next request comes you can perform your required logic.
I have an asp.net web form. when a user authenticate, it create a Secured cookie called .aspxauth
uppon logout, I call these 2 methods
FormsAuthentication.SignOut();
Session.Abandon()
Problem is that we had penetration test and if I steal the cookie, logout and manually reinsert the cookie, I become loggued in again. So the .aspauth isn't invalidated server side.
I've googled it and I can't find the answer to that security breach.
Microsoft has acknowledged this issue here: https://support.microsoft.com/en-us/kb/900111
They offer several ideas for mitigating this vulnerability:
protect the application by using SSL
Enforce TTL and absolute expiration
Use HttpOnly cookies and forms authentication in ASP.NET 2.0
Use the Membership class in ASP.NET 2.0
Regarding the last one, I'll paste the contents from the site for convenience/preservation:
When you implement forms authentication in ASP.NET 2.0, you have the option of storing user information in a Membership provider. This option is a new feature that is introduced in ASP.NET 2.0. The MembershipUser object contains specific users.
If the user is logged in, you can store this information in the Comment property of the MembershipUser object. If you use this property, you can develop a mechanism to reduce cookie replay issues in ASP.NET 2.0. This mechanism would follow these steps:
You create an HttpModule that hooks the PostAuthenticateRequest event.
If a FormsIdentity object is in the HttpContext.User property, the FormsAuthenticationModule class recognizes the forms authentication ticket as valid.
Then, the custom HttpModule class obtains a reference to the MembershipUser instance that is associated with the authenticated user.
You examine the Comment property to determine whether the user is currently logged in.
Important: You must store information in the Comment property that indicates when the user explicitly signed out. Also, you must clear the information that is in the Comment property when the customer eventually signs in again.
If the user is not currently logged in as indicated by the Comment property, you must take the following actions:
Clear the cookie.
Set the Response.Status property to 401.
Make a call to the Response.End method that will implicitly redirect the request to the logon page.
By using this method, the forms authentication cookie will only be accepted if the user has not been explicitly signed out and the forms authentication ticket has not yet expired.
Read this article about Session fixation and how to get rid of it once and for all:
http://www.dotnetfunda.com/articles/show/1395/how-to-avoid-the-session-fixation-vulnerability-in-aspnet
This remains an issue in .NET Framework. Everyone seems to think Session.Abandon() is the answer, but the sad truth is that command does not invalidate the session on the server's side. Anyone with the right token value can still resurrect a dead session, until the session expires based on the Web.config settings (default = 20minutes).
A similar questioner posed this question a long time ago here:
Session Fixation in ASP.NET
Most of those links are dead, and Microsoft has no new news on the topic.
https://forums.asp.net/t/2154458.aspx?Preventing+Cookie+Replay+Attacks+MS+support+article+is+now+a+dead+link
Worse still, you're still vulnerable to this cookie replay attack even if you're implementing a completely stateless MVC application and don't use the Session object to store data between views. You can even turn off session state in the web.config settings and still replay cookies to gain access to a logged-out session.
The true solution is hack-y and described here, and you need to have session data enabled InProc to use it.
When the user logs in, set a boolean value in the session data, like Session["LoggedIn"] = true;, which is stored on the server side.
When the user logs out, set that value to false.
Check the session value on every request--an attacker trying to replay a session isn't going to be nice to you and come in through the Login page only. It's probably easiest to do this using a custom filter and registering it globally in the global.asax file (so you don't have to duplicate the code everywhere, or attribute every controller/method).
Even if the attacker has all the cookie values, they won't be able to re-use that same session ID, and the server will automatically delete it once it reaches the specified timeout.
if you are using the FormsAuthentication, you can use this code. By using this code you can destroy the created cookies by setting the Expire property of HttpCookie. It will help you:
FormsAuthentication.SignOut();
Session.Clear();
Session.Abandon();
Session.RemoveAll();
// clear authentication cookie
HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
httpCookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(httpCookie);
I am very confused in my implementation of sessions in asp.net web application. My logic is once user enters user name+password, I validate credentials and then create a new session with some user info[All I am after from this point onward is that this user has access to restricted resources and a user must never be able to access those resources unless he/she is authenticated]. This I validate on each request and the rest. Here is my issue though. I have many places in the website where I have html links, and I read that if I have a link such as
<a href='resource1.aspx'>resource 1</a>
This will generate a new session id, hence in reality invalidating the existing session id, which in my case will be treated as session expired and user is sent to login page. While reading up on this issue I came across an asp.net API method[
Response.ApplyAppPathModifier(url);
] which prepends the session id to each request hence resolving the new session id generation for each link. Though it resolves session breaking issue it does add the session id next to all of the urls and now session id can be seen in the source code( view source for web page). I really don't want to use cookies and want to use session for user sessions...Can some one please help me create a system which will work the way I wish it to ? if I am doing it utterly incorrect, I would really really appreciate a details discussion and if possible some example...Thanks you much in advance..
It looks like you are trying to use cookieless sessions which add a session id to all links in order to be able to track the sessions.
The other (much more common, standard and IMO secure) approach is to use normal sessions, which auto creates a session cookie (when you use the .Session object), and uses that to determin the current session. If you don't want a cookie you'll have to stick with cookieless, and the session id in the url.
In my web application I test for a condition on one page and want to retain the results of the test for a specified duration (such as 5 minutes). I can do this with a cookie, of course, but just in case a user has disabled cookies, I'm thinking a custom server varible might do the trick. I've heard about this, but I haven't been able to find out to do it.
Alternatively, maybe a session variable might be better? There's no inherent way to expire these, right? How long would such a variable survive before IIS tosses it?
Asp.Net has session state. Each Asp.Net Page has a Session property. You can also access it via HttpContext.Current.Session, though there is a subtle difference that won't matter until it bites you (which see my answer to the question, Difference between Session and HttpContext.Current.Session.
The default session state configuration is in-memory. That means that if your web site is served up from something like an F5 Networks Big IP (load balancer) cluster, unless the load balancer is set up to be 'sticky' (meaning that once assigned to a machine in the cluster, you'll always hit that machine unless it goes down or is otherwise removed from the cluster).
If your clustered web site doesn't have sticky sessions, your session state will vanish when your request hits a different machine...and then reappear when another request hits the original machine. You can guess how much fun that can be.
There is built-in support for SQL Server session that you can enable in your web.config. Once set up that way, you're using SQL Server as the backing store for session state. That solves the server farm issue noted above, but does so at the expense of hitting a SQL Server each and every time a session state value is accessed. That slows down access considerable, especially if the session size large. Oddly, executing a SQL query and shoving a 500kb session blog across the network every time you access a session state setting can negatively impact performance. Who knew? [Don't ask how we found that out].
There are other solutions to the problem: ScaleOut's products come to mind (e.g., ScaleOut SessionServer).
Or you can roll your own session state provider using something like an AppFabric cache.
Another "feature" of using SQL Server sessions state is that anything going into Session must be ISerializable.
You can't set a server variable; instead, using Session, which is tied to the current user, is the best approach for user-based data. For application-based data, you can consider cache. So assuming the former, do:
Session["Key"] = MyValue
Note that session lasts 20 minutes; if you have to have exactly 5 minutes, you can use cache, which you can explicitly expire at 5 minutes:
Cache.Add(CurrentUserID.ToString() + "Key", "Value", .. TimeSpan.FromMinutes(5));
You can use the ID of the current user to make the cache value specific to a user, or use cookies, but set HttpOnly=True on the cookie object. An HTTPOnly cookie is only on the server and never accessible on the client, as such:
varcookie = New HttpCookie("Key", Value);
cookie.Expires = ..;
cookie.HttpOnly = true;
We have a page of search results which the user can hit in several ways. 90% of the ways will set up a 'Search Criteria' session object, which the results page will use to retrieve the search results.
When the session object isn't found, we will typically show the user an 'invalid search' message, and give them a link to the main search page.
The exception is the case where the user hits a webpage which has the search results page as it's default page (we use .NET's themes to provide private labels for our site, skinning it with our affiliates' colors and logos). If the search results page is the default page for the site, there is a special search that is preformed when there is no session criteria.
This is working fairly well in our testing, but there is an edge case we would like to handle: When a session expires while someone is on the search results page (having come from the search page) and they then click on the next page of results, they will get this special search instead of the 'expired session' message.
This is the basic format we're using, where searchCriteria is set from session.
if (searchCriteria == null)
{
if (/*Check if this is the default url for this site*/)
{
//Preform special search
}
else
{
//Display 'session expired message'
}
}
Is there a way we can check Session in the inner if block to see if the user's session is new due to expiration of an existing? Or do browsers just throw away the session cookies when they expire?
Is there a browser difference? Do some return the expired session cookie to the server, while other's delete them on expiration? Or is it consistent?
This is an excellent article which is based off of this one. I think you will find your answers here (Page 2 of the second article specifically)
All the browsers will return the expired session cookie. They'll do so until the browser is restarted or it's rewritten by a server response.
The answer from bnkdev uses this fact to detect new vs expired by seeing if the cookie is already set. It's simple and easy and will likely work for you, but it only works when cookies are used for session ids. It won't work for cookieless sessions.
Also, rather than hard coding "ASP.NET_SessionId", you should probably fetch it from the cookieName attribute of the sessionState configuration element.