Synchronizing ASP.NET Sessions Across Multiple Sites - asp.net

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

Related

Single Sign On

Do we need to use out proc sessions while implementing SSO?What will be the limitation of inproc?
which is best way of implementing SSO across domain?
The use of inproc session vs. persisted session has little to do with SSO. The main limitation of inproc sessions is that it won't work in a loadbalanced setup, but again, it has little to do with SSO. The easiest way to implement SSO is to use the Windows Identity Foundation (WIF), which is part of .net framework 4.0 (there is also a version that works with .net 3.5).
Basically you just implement a passive STS. There are several walkthroughs out there.
If both of these applications are using forms authentication then the solution is easy. All you have to do is configure the machineKey on both applications to be identical and set the domain on the forms cookie to be .exampledomain.com for both web.configs.
If you're using a custom authentication scheme built around session variables, you might want to consider configuring both servers to point to the same SQL Session State database. If you go this route, you can modify the GetTempAppID to always return 1 and configure the machineKey on both applications to be identical. Just another suggestion from your friendly sheero. HOI!
inproc sessions will be an issue if your application is running behind the load balancers, so you might want to think about SQL server based sessions, plus you also need to think about if you really need a usual SSO that just keeps you automatically logged in, like if your user has different rights/permission set on different sites then you might want to add some custom code in your SSO login piece, as you have mentioned that you are using ASP.Net 2.0 so i am assuming you might be using the .Net role based profiles for group security and permissions, so you also might want to check if you get your self in a scenario where your logged-in user has different permission set in your different sites. So for me its not just SSO its custom login code for a specific requirement you might want to look into.

User + session handling with ASP.NET and mySQL solution

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.

Redirect to a different web application with associated data

I'm building a solution where 2 applications are involved.
One of them handles the login and user management, and and other provides the service itself.
I need a way to send the user from the first app to the second, along with some data that derives from the whole login process.
The data has to be sent in such a way that it can't be tampered with; or a way to check if it's legit has to be available.
Some more details:
The solution consists of 2 ASP.NET (Webforms) websites
Although both websites are sitting on the same server, a solution that doesn't rely on this is prefered
Thanks in advance.
It might not be the best solution.
But this is what immediately comes to my mind.
Serialize the data, (from first website) that you need to pass, into a database accessible from both web sites (can be a third server in worst scenario when your both website might be sitting on different server).
Generate a key for the serialized data in the database. It can be a GUID. Pass it on to the other web site. Other website can delete it immediately after retrieving it by using the give key.
You could set an encrypted token cookie in the login application and pick it up in the management application.
I don't know of any way to transfer state data between applications on the server.
I am not if it is possible to use Server.transfer to the second site. But this would definitely be tamper-proof since it would occur on the server. The landing page on the second side would then persist the transfered info. Context object would be a good location to store the transfered info.
At a minimum it would recquire both apps to be on the same server.

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.

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