Over at TechEd South East Asia I had an argument with Clemens Vasters about whether it is safe to do online banking on a machine in an Internet cafe. He said it's absolutly crazy, just like having unprotected sex. I agree it's not a good idea but I'm on the road for 13 months now and have no choice other that check my account once in a while and transfer some and pay bills. I wouldn't say I'm unprotected though. Here's a list of things I do when before I connect to my bands web site:

  • I check the location for any cameras that may record my screen
  • I make sure I have administrative rights, otherwise I'm going on to the next place.
  • I use task manager to check for the obvious viruses
  • I plug in my USB drive to get access to all my tools.
  • I execute my script to kill all user processes.
  • I manually check how well that worked and kill the remaining application.
  • I shut down all third party and non-essential Microsoft services, I really should write a script for this too.
  • I run the www.sysinternals.com RootkitRevealer to find any root kits, which are not visible to the Windows API or Anti-Virus software. This takes a while to run and you have to look at the results carefully.
  • I use Firefox to connect to my bank's site, never use IE, it's much easier to track keyboard and mouse clicks in Internet Explorer.
  • I double check that I'm using SSL/https and that the certificate looks okay.

I would say that I'm now possibly more secure than many workstations within Microsoft, just look at all the stuff those guys are having on their laptops during presentations.


 
Categories: Work on the road

September 9, 2006
@ 09:35 AM
The asp.net session object is a great way to keep user specific data throughout the lifetime of your web application.

However I have two fundamental problems with it:
1. Sessions out of the box don't work in Web gardens or web farms, you can use the asp.net session service or a SQL database to manage your session state, but that is slower than the default inProcess session state. Even for smaller sites there are problems; every time I update web.config or an assembly in the bin directory I loose my sessions. In addition every time the worker process is restarted through IIS health measures, sessions are gone as well.

2. I need to use user state within my business objects because that's where my authentication and authorization code resides. It's possible to access the session object in your business tier but they don't work if I access it from a console application or nUnit for testing.

Today I started working on a solution and have something working but it needs more testing.  First to make things cleaner I abstracted all access to the session and cache objects into a new class in my business layer called 'State' all access to state variables has to go through this class. So I have get, set and remove methods. Each take an enumeration of items rather than a string for the key to keep a nice clean list of all session variables I'm using.

Within this class I can now address my two problems. To solve the loosing sessions problems I bring in a custom database table that stores session variables for me. Not quite as sophisticated as the Microsoft's SQL-Server solution but it works. When I save 'state' I not only store it in the session object but also in the database table. When I try to access 'state' I first check session and if that is null, then I check in the database. If I find the value in the database table I put it into session and return the value. This way the database is only accessed when a value is created/updated or when we lost the session object, otherwise we use the fast in memory session object.

Some considerations:

I'm only using this methods for integer and small string values, but not for my 'state' with datatypes of Hashtable or even DataTable. This would involve some serialization to store these types in a database field. In my case these 'bigger' values could be rebuild from normal database data based on the integers stored in state. (I have an integer UserID and hashtables for a security token and a DataTable for navigation data, both can easily be refilled when needed, remember this only happens when we loose session).

I mostly use 'read-only' state. All my session variables are set after a user has been authenticated and after that, they are never updated. This also works fine in web gardens and web farms because the session objects in all the various worker processes are synchronized through the database table.

For session variables that change during their lifetime this approach only works for a single worker process. If you have multiple processes that update state in there own inprocess session object there is no way to notify the other worker processes. One idea is to check the database periodically for updated data.

In my case I use the state variable to identify that user after initial authentication. When the user logs out, I remove the state from the inprocess memory and the database. However if I'm using multiple worker processes, the other ones still have the state data in their local session objects. The only solution I see to this problem is that you also have to delete the Asp.Net_SessionID cookie, so when the user hits another worker process it is no longer associated with it previous session. Of course this means it's all or nothing, you can't remove some state values but not others. For web-farms and web-gardens you should really only use this for write-once state data that should also be deleted together.

What about expiration. My method to remove a session variable also deletes the associated record in the database but it doesn't expire in the same way that in-memory sessions variables do. Deleting all related records when the Session_End event in globals.aspx fires is one option.
This all works because the Asp.Net_SessionID cookie remains in the browser even if you loose your session on the web-server. The new worker process picks up the existing cookie and uses the same ID for the new session instance.

This allows you to restart IIS or even the server and not loose state for the user, great!

The second problem I solved by checking for an existing HttpContext.Current instance, if this doesn't exist I am not in a web application and can't use Session or Cache. In this case I am using using my own Hashtables to store state information. I implemented a singleton pattern for an AppContext class to ensure that I have always only one instance of my Hashtable.

All this shouldn't be to hard to implement, you should even be able to do this in classic Asp or php, there is nothing asp.net specific about this, session variables are widely supported. I don't have any example code for this yet because it's all deeply integrated into my application. Lets see whether there is some interest.


 
Categories: ASP.Net