User + session handling with ASP.NET and mySQL solution - asp.net

I've been reading around the web about different alternatives to keeping track of users but I can't seem to find the "perfect" solution for my situation.
The app will (hopefully) be high-volume so I'd like to design with scalability in mind. It might be necessary to host the site using several web-servers so session mode InProc won't work, right? It's kept in memory of the current web-server and since the user might jump from web-server to web-server I can't be sure the session will be kept connected to the user.
Do I need to make a custom membership and role provider that works with mySQL to be able to use the .NETs standard user handling systems (like FormsAuthentication that can handle session stuff from what I've understood)?
Best practices are very welcome as well as empirical experiences of similar scenarios. (Of course any feedback is welcome really :) )

MySQL
Marvin Palmer has an article on Implementing .NET Membership and Roles using MySql.
Session
In terms of handling Session state, you're correct in your assumptions above. You can implement Sticky sessions to ensure that visitors are routed to the same web server. This might be an optimization before its time, though. Face those challenges when you get to them.
You can help yourself out by ensuring that you abstract away all your Session["foo"] calls right now into a static class. If you haven't already, make a static class whose job is solely to deal with setting/getting session values. Make a property for each key, and access them from your application as MySessionMgr.CustomerID;. When/if your session persistence mechanism changes, you only have to change it in that class.
In the future, you might consider Windows Server AppFabric (previously codenamed Velocity), Microsoft's multiple server shared session technology.

Related

How to maintain User-session with ASP.NET MVC

Hey folks, I would like to know is there any way i can maintain stuffs like log-in,log-out,user-session..etc without using membership in ASP.NET MVC?
Faraaz.
There are three provider models concerned with the areas that you are referring to.
The MembershipProvider is concerned with authentication, validating users and storing data related to the user such as last login date, username, etc.
The RoleProvider is concerned with authorising users for particular areas of your application.
The SessionStateProvider is concerned with storing session for your application.
You can write your own custom provider for any of them if the default providers are not suitable. You could roll your own authentication, authorisation, or session management without the providers, however there would be quite a bit of work involved more so than implementing your own custom provider.
You can use the Session object to store session scoped data.
But for authentication/authorization you will need to come up with your own scheme.
You need to use the Session dictionary and a session state server. See http://msdn.microsoft.com/en-us/library/ms178581.aspx for more info.
Word of warning: In my experience the InProc session state mode only preserves the values you put into Session for the lifetime of the current HTTP request. They don't persist across requests as you might expect, even when you're using a single HTTP server and you'd think in-memory storage would persist. This may only occur while debugging using the built-in http server in VS2010, but even so it can cause you a lot of trouble trying to understand why state information isn't being saved.

User roles - why not store in session?

I'm porting an ASP.NET application to MVC and need to store two items relating to an authenitcated user: a list of roles and a list of visible item IDs, to determine what the user can or cannot see.
We've used WSE with a web service in the past and this made things unbelievably complex and impossible to debug properly. Now we're ditching the web service I was looking foward to drastically simplifying the solution simply to store these things in the session. A colleague suggested using the roles and membership providers but on looking into this I've found a number of problems:
a) It suffers from similar but different problems to WSE in that it has to be used in a very constrained way maing it tricky even to write tests;
b) The only caching option for the RolesProvider is based on cookies which we've rejected on security grounds;
c) It introduces no end of complications and extra unwanted baggage;
All we want to do, in a nutshell, is store two string variables in a user's session or something equivalent in a secure way and refer to them when we need to. What seems to be a ten minute job has so far taken several days of investigation and to compound the problem we have now discovered that session IDs can apparently be faked, see
http://blogs.sans.org/appsecstreetfighter/2009/06/14/session-attacks-and-aspnet-part-1/
I'm left thinking there is no easy way to do this very simple job, but I find that impossible to believe.
Could anyone:
a) provide simple information on how to make ASP.NET MVC sessions secure as I always believed they were?
b) suggest another simple way to store these two string variables for a logged in user's roles etc. without having to replace one complex nightmare with another as described above?
Thank you.
Storing the user's role information in a server-side session is safe providing a session cannot be hijacked. Restating this more broadly, it does not matter where user role info is stored if an authenticated session is hijacked.
I advise not putting too much faith in the article you linked to, but the 2002 vintage report linked to from your link is of interest. Here are my take-aways:
Don't accept session IDs embedded in URLs.
Focus your time on eliminating cross site scripting dangers i.e. scan all user supplied data and parse out executable java script.
Issue cookies for complete domains (e.g. myapp.mydomain.com)
Host your domain at a high class DNS operator e.g. one that only allows DNS changes from a preset remote IP address.
Don't issue persistent session cookies.
Reissue a session cookie if someone arrives at a login page with a sessionID already associated with an authenticated session.
Better still, always issue a new session cookie on successful authentication and abandon the prior session. (Can this be configured in IIS?)
The only way to make a secure cinnection is to use SSL. Anything less than that, and you simply have to make the evaluation when it's "safe enough".
A session variable works fine for storing a value, with the exception that the web server may be recycled now and then, which will cause the session to be lost. When that happens you would have to re-authenticate the user and set the session variable again.
The session variable itself is completely safe in the sense that it never leaves the server unless you specifically copy it to a response.
Have you considered setting up a custom Authorize tag in MVC. I gave an example of this in another question.
On initial authorization (sign-in screen or session start) you could seed a session value with the IP address also. Then in your custom authorization, you could also verify that IP's still match up as well. This will help make sure that someone isn't 'stealing' the person's session. Everytime you access your session data just make sure to pass the requester's IP and have some check on it.
Are you trying to control the access to functions at the client level? That is the only reason I would expose the roles and items to control client side functions.
Alternatively, you could create a function to obtain the items that the roles of the user are allowed to use, and then even if the function is called outside of the items given back to the web application, you can prevent the user from accessing them.
4Guys seems to show how to control functions with the roles.
The approach I have used in the past is to use symmetric encryption of a cookie alongside SSL. Encrypt the user information in the reponse and decrypt it in the request. I'm not claiming this is foolproof or 100% secure and I wouldn't want to do this on a banking application, but it is good enough for many purposes.
The main issue with session variables is that if you store them inProc rather than persisting them, then you need to apply 'sticky' sessions to your load balancing in a web farm environment. Guffa is correct that without this persistence session variables will occasionally be lost causing a poor user experience.
Sticky sessions can lead to uneven load balancing, perhaps reducing the value of being able to scale out.
If you are going to be be persisting the sessions so they can be accessed by all servers in your web farm, you may be better off using a Guid to identify the user, encrypting this in a cookie and retrieving the user record from your data store each time.
My obvious question is that why do you want to store a users role in session ?
Here is my answer to your query, how this helps. I have attached a small demo application for you to take a look at and understand my points. When you open this project in visual studio, click on the project tab on the top and select asp.net configuration. From the page that will show up you can do the user administration stuff.
You need to store the roles of a user in some secure manner ? The answer to this question is that there is no need for you to worry about storing the role for any user, when we have the asp.net membership, profiles and roles framework to help us out on this. All you need to do is create a role in the aspnet database and assign that role to the user.
Next you want to store two string in some secure manner. I suggest you user profile for storing user specific information. This way you have the information available to you where ever you want from the profilecommon class.
Also please see the attached demo application placed at the end of my blog http://blogs.bootcampedu.com/blog/post/Reply-to-httpstackoverflowcomquestions1672007user-roles-why-not-store-in-session.aspx
Just a suggestion, you might consider using this little library:
http://www.codeproject.com/KB/aspnet/Univar.aspx
It has a server side implementation of the cookie whereby all cookies can be stored on the server while asp.net authentification is used to identify the user. It supports encryption and is also very flexible making it very easy to switch from one storage type to another.

Storing Username/Password During Processing

Working inside the context of an ASP.NET application I am creating a page that will be able to execute database scripts against one of many databases in our environment. To do this we need to prompt the user for a username/password combination, this value can be used for all servers without issue.
The question is where is the most secure location to store this information? We need to store it temporarily as when they are on this specific page they could be executing hundreds of scripts, over multiple postbacks. From what I can tell I have 3 options and I'm not sure what is the best. Below is my take on the options, what is the recommendation of everyone here? What is the most secure, while still being friendly for the user?
Store Information In Viewstate
One of the first ideas we discussed was storing the information after being supplied by the user in the ViewState for the page. This is helpful as the information will only exist for the lifetime of the page, however, we are unsure of the security implications.
Store information in Session
The next idea we had was to store it in session, however, the downside to this is that the information can be made available to other pages inside the application, and the information always lingers in memory on the server.
Store Information in Application
The last idea that we had was to store it in the Application cache, with a user specific key and a sliding 5 minute expiration. This would still be available to other pages, however, it would ensure that the information is cached for a shorter period.
Why?
The final question that is important is "Why are you doing this?". Why don't we just use their Lan id's? Well we cannot use lan id's due to the lack of network support for delegation.
S0 what is the recommended solution? Why? How secure is it, and can we be?
Update
Great information has been discussed. TO clarify, we are running in an intranet environment, we CANNOT use Impersonation or Delegation due to limitations in the network.
In my opinion the natural place for this is the Session.
I'm not sure why you seem to be fearing "other pages inside the application" (you control the appliciation, don't you?), but if you really are, you could use some sort of encryption before you store it.
But if you are going to do that, the data could live in the ViewState as well.
I don't like any of these ideas, but totally hate the viewstate idea.
I don't know how many databases you are attaching to, but if there is a limited number, I kind of wonder if handling your authentication and authorization in a standard secure manner, then connect to those databases via integrated security using identity impersonation with an account that has minimal permissions.
The ViewState approach is good but has the problem that you are giving out the username and password to the client. Even if you encrypt it, if some attacker has the encryption key, the situation will not be very good.
Regarding the Session and Application approaches, I don't think Application approach makes sense. Data is user specific, so Session should be the way to go. It'll go away as soon as user's session is closed. By the way, if you chose to store it at the server, use SecureString class.
As John MacIntyre wrote you should use integrated security and impersonation for this.
If for some reason you can not use it and you are going to provide your own login page, use by all means SSL to encrypt the traffic between the browser and your server. Using the ViewState approach is also completely insecure if you do not use SSL, there are tools to view the contents very easily. From the methods that you enumerate the best one would be to use the Session state. You can offload saving the session state from your web server memory and save that data in a database that you can secure the way you want. If you don't like the way these work you could even write your own session state provider and apply the security you need there.
Storing in Viewstate increases your exposure because the password will be flying around the internet again and again. It's up to you if encryption is good enough to address this risk.
Using Application or Session both keeps the password in the server. As mentioned above SecureString will keep people from simply reading passwords out of memory. Session will scale to more users, and probably more importantly to multiple servers much easier than Application. Unless you are sure you will never use more than 1 web server I would not use Application, as it will be up to you to synchronize all the servers.
Never store passwords!
Rather store the hash of a password. See: http://en.wikipedia.org/wiki/Crypt_(Unix)#Library_Function.
I'm aware this does not answer the question, but the more programmers who ignore this advice, the easier it will be for criminals to steal data. Don't let your organization become a news story.
The username/password really shouldn't be stored anywhere.
You store a live database connection, preferably from a pool in your Session object. You only need the username/password as long as it takes to log into the database.
While another page can use the live connection, it doesn't give anyone else permanent access to the database as you would by storing a username/password.

Synchronizing ASP.NET Sessions Across Multiple Sites

Is there an elegant solution for synchronizing sessions across multiple ASP.NET applications? I'm sure this could easily be considered a security hole, but there is a 3rd party ASP.NET application involved, for which there is no ability to extend. For this reason, a second [related] site is being developed, but will require direct access to the sessions created on the 3rd party application.
As an example, when a user logs in/out of one site, the same operation should occur on the other site. However, it's important to note that this goes beyond a typical SSO.
Using SQL Server to store is one of your most easy solutions.make sure you have proper permissions set on the SQL objects. I am not familiar with what Manu has suggested. There is actually one more way of doing it which is a little difficult. Its done by implementing a modification of the memento like pattern. App1 stores session info in the database but instead the other application App2 getting access to the DB, the session info is exposed via a service which App2 can reference. Once the user moves on to app2 and is authenticated, its session is restored using the service.
Hope that helps. It worked for me in one of my projects.
Try memcached session state provider: http://www.codeplex.com/memcachedproviders
Since the cache runs in a seperate service, I am pretty sure you can access the same storage pool from different apps.
Cookies are an option assuming the application is storing some key data in its cookies. If the other site is in the same domain, it can read them.
Use NCache - http://www.alachisoft.com/ncache/
It'll help you to acheive what you are looking for.
It has built in distributed ASP.NET session state cache as well, and will help you to share sessions across multiple sites. Details Here

Passing session data between ASP.NET Applications

We have several ASP.NET applications deployed to a few servers. Is there a standard way to reuse session data or some other method to not require users to log in to the next application when moving from application to application if they've already authenticated? I'm hoping there's a best practices way of doing this that you guys know about. I feel like there should be something easy that I'm missing.
Thanks.
Edit: To be be more clear, the main info in the session that I'd like to pass is the authenticated userid, but possibly some other session variables as well.
you could implement a single-signon strategy for your applications.
http://aspalliance.com/1545_Understanding_Single_SignOn_in_ASPNET_20.all
http://blah.winsmarts.com/2006/05/19/aspnet-20-implementing-single-sign-on-sso-with-membership-api.aspx
http://johndyer.name/post/2005/12/Single-SignOn-with-ASPNET-Membership-and-WebServices.aspx
http://msdn.microsoft.com/en-us/library/ms972971.aspx
Single Sign On (SSO)
http://msdn.microsoft.com/en-us/library/ms972971.aspx
For the session check this: http://www.codeproject.com/KB/aspnet/Sharing_session_state.aspx
Complement with this so the cookie is shared: http://mgrzyb.blogspot.com/2007/12/aspnet-and-subdomains.html
It's not clear from you question if you're just concerned about logons, or if you really need to share session data between applications.
Assuming the latter, you could try something like this:
first, make sure all the appliations are running in the same domain. If not, all bets are off. I don't know if there's a simple way to configure the domain property of the session cookie yet, so you may have to do it yourself, by setting the cookie domain property to the domain:
Response.Cookies["ASP.NET_SessionId"].Domain = ".mydomain.com";
you'll need to make sure that each application is configured to use either a common state server, or a db-backed session.
Sharing a sign-on between applications (covered above) is quite a different ball game to sharing ASP.NET Sessions between applications.
Why do you want to share Sessions between applications?
ASP.NET Session is a metaphor for a user's current interaction with one ASP.NET application. It exists in ASP.NET to give us a place to store temporary state data between the various page requests that a user makes while using your application.
If your applications are very closely related, e.g. the user uses both at the same time, or almost the same time, you could consider merging them into a single ASP.NET application.
If your applications are not that closely related, perhaps they should be sharing the same database as a means to exchange data, or using an API e.g. based on Web Services to exchange information.
Hope that helps.

Resources