How to handle sticky sessions issue? - c#

I am running into this strange issue where few users of my app plug out their laptops from dock and move to WIFI network while using the application, Now after changing the network when they click on any navigation in the application it takes them back to the login page mentioning the session has expired.
Background: The server where the application is hosted have the load balancer which dynamically routes the incomming request, hence when user goes of from one network to another the old session maintained by the web browser stays open but load blancer identifies it as a fresh request and hence allocate to next available server which requires a login, now if user is fortunate to be routed on the same web server where he was before then all works fine otherwise he is redirected to new web browser.
Please help me resolving the rare scenario issue.
Thanks in advance.
Vishal

This issue depends mostly on your load balancer and the persistence of stickiness.
Some balancers handle the sticky persistence internally, so they have a table between client IP and route. Your case sounds like that.
Now, if you shift the persistence from the internal table to a cookie (or URL appendix), you can tackle the case. By using a cookie, the client will send the cookie on every request and the load balancer can check, whether the requested route is still valid and then serve the request. There is a non-IIS example for Apache (http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html#stickyness_implementation), how they approach stickiness, but the feasibility depends on your balancer.

Since you have load balancing in-place then it is just a questions of whether to store the sessions in Jsession or Cookie, to avoid this issue I suggest your configuration the server to use Cookies. As by default Tomcat 7 (and I believe Tomcat 8) are configured to use Jsession

Related

Using different client certificates for different routes

I'm working with an SSL application and I would like to read data from two client certificates.
When a user comes to my site he chooses a certificate and enters a pin, which get cached and used by subsequent requests until Chrome (et al) gets restarted.
Any ideas on how to prompt the user for a certificate for a second time on the same site?
Regards.
A solution that has satisfied my need was to bind the app on two https ports in IIS config. Works on IIS Express also.
More info: I am making two ajax requests on routes that are matched by a single <location> tag web.config. This location requires a certificate, which means user gets prompted when accessing them. Since these two ajax calls go to different ports, user gets prompted on the second ajax call too.
Knowing how to clear the cache would have been nicer for other use cases, because restarting Chrome is not something I would ask my users to do.

Force SSL Session to Timeout on server or client

My asp.net mvc 5 application is configured on IIS to require SSL and a client certificate in order to authenticate. I would also like the user to be able to terminate that session explicty by clicking a link/button (SSL session, not HTTP. No HTTP session is ever created).
Closing the browser seems to work with all browsers. If I do this, the next time I try to access the site I will be forced to start a new SSL session (i.e. choose a client certificate to authenticate with). Effectively, closing the browser clears its SSL cache.
If I could do this programmatically on the client, using javascript, that would be great. Or, preferably, I would like to force the server to expire it's end of the SSL session, using C#, that would be better.
This question has been asked twice before, with 0 answers given. I'm trying to get a fresh set of eyes on it, in the hope that PKI authentication is more common now than 2-4 years ago:
IIS - Reset SSL Session Programmatically
Is it possible to close/manage a SSL connection/session on IIS?
A SSL session is either known by client and server or it is not known. There is no API to delete a specific session on the browser, i.e. all you can do is close the browser. The situation is similar on the server side, especially if the stateless session tickets are used to maintain a session. In this case it is not possible to remove a particular session but it is only possible to change the server side secret used to create these tickets which causes all sessions created with this secret to be invalid.

Restart remote IIS site in another site

I have more than one site on iis. Some sites working on another machine also but they are using same database.
Sites have caching mechanism. One of the site using for making customization about sites. Customization are saved on DB.
I want to reset caching for sites which are effected from customization. I can found two thecnique for this.
I want to asking for another solution.
Technic 1: adding restart endpoint for sites in web.config file and calling them when change made by user.
Technic 2: using db events for catching changes (in asp.net application may be I can't get changes because of sites dying after idle time)
Both of the techniques listed in your question have drawbacks. Technique 1 restarts the entire server, which is over-kill. Technique2 has the drawback you list, and is relatively complex to implement.
The approach I use is to provide a controller action that invalidates caches. That action requires authentication, and can be accessed either via an administrative web page on the server (single instance server), or can be invoked by accessing the URL of the controller action and providing appropriate credentials (server farm, invoke e.g. https://ServerNameOrIp/Admin/InvalidateCache once for each server/IP in the farm).

Retain session when calling from a different website

I have two website consider it as website1 and website2.
In website2 there is a login page .When a user click on the login button it will call a HTTPhandler in website1 to authenticate user.On successful authentication user information will be stored in a Session variable from handler.
Then it will redirect to a page page1.aspx in website1.But the previously set session is not available in the page1.aspx .What will be the issue?
I checked the session id in first request(when calling handler in website 1 from webiste 2) and Second request( redirecting to the page1.aspx from the handler) the session id is different.
How can i retain the session data?
You need to store session data in another process shared to both web site.
You can do it intwo different ways:
Configure an SQL server
Configure SessionState service, a Windows service used to share informations.
In both cases you have to change both web.config files to support the new session mode.
I.e. to use SQL:
Prepare a database (from command prompt):
cd \Windows\Microsoft.NET\Framework\v4.0.30319
aspnet_regsql.exe -ssadd -E -S localhost\sqlexpress
Modify web config as following:
<sessionState mode="SQLServer"
sqlConnectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Test" allowCustomSqlDatabase="true"/>
You don't need to change your code.
Correct me if I an wrong, AFAIK different domains cannot share a single session. One way to handle this is to carry the data to the other site through cookie [encrypt the values for security], then copy this cookie value to the session in the other site receiving it and destroy the cookie.
And if the sites are in different servers you need to handle the "sticky session" so that servers share the session.
This situation sounds kind of similar to one I have experienced and worked on before, where one web application acts as the login page while another is the actual app where all your work is done. I can describe what I did in the hope that you find it useful.
Like you I had one web app which had the login page (so in your example this would be website2). When the login form submitted I then redirect to a fake Login.aspx page in website1 - this is where we differ I think as I'm not sure of your specific reason for using a HttpHandler.
In my case the website2 Login.aspx page is actually just the way into the web application; it has no markup, just code-behind which will authenticate the user, perform setup (e.g. set session variables) and then redirect to another page such as Homepage.aspx. This particular scenario has worked for me, so maybe your problem revolves around the use of a HttpHandler though I would not be able to tell you why.
In order to retain the same session date across two different servers running ASP.NET web applications you must configure your session state to be managed out of process. This means the actual session state data variables will be stored outside of worker process and in another process that is able to make the session data available to other machines.
To achieve this you can configure your application to use SQL Server to store session state and make it available to multiple servers in your farm. The TechNet article Configure a SQL Server to Maintain Session State (IIS 7) provides details on hor this is done in IIS 7.
If you are using IIS 6 then the steps to configure are somewhat different and I can provide further details on this if needed.
In order for this to work you do need to ensure that both servers are running applications within the same domain, e.g. myapp.com, otherwise the ASP.Net session cookie will not be passed between the two servers. ASP.Net uses the cookie to lookup the session state stored in SQL Server and will therefore not find any matching session if the cookie is not passed on requests between the two servers.
i think IRequiresSessionState will not help because context is different.
once we had the same problem but that was passing asp session varibles to .net. How ever you can do it here also.
on both website create a page setsession.aspx
now if you are on page say web1/page5.aspx and want to go to web2/page3.aspx
you redirect to web1/setsession.aspx?togo1=web2/page3.aspx
in both setsession.aspx logic in to extract sessiondata and place them in querystring
so the web1/setsession will redirect to web2/setsession.aspx?sess1=value1&sess2=value2&togo=page3.aspx
web2/setsession.aspx will check for togo querystring and if found will extract all querystring name and value will set them in session and will then redirect to togo value.
you need to differentiate togo1 and togo carefully.
Session sharing between websites is going to require hand-coding. You could hack the asp.net framework to get this working, but I feel that this is not a clean way of achieving what you set out.
If user authentication is all you are doing from website, is it possible to use alternative? Single Sign On mechanisms will help you out here.
Something like SAMLSSO could help you in this case.
You have two websites which are hosted on different servers, it means you have two different processes running on separate machines, so sessions will be definitely different. Same session can't be shared across processes because by default asp.net support in-memory session.
Here you would need to think about storing sessions information which can be shared between two processes (i.e. out of process). Ideal way to store sessions information in databases. For this you can consider Stefano Altieri code sample above.
I don't think you really want to share session information between two websites at all. From what I can gather from comments, what you're really trying to do is have a user authenticate in one website (give you a username and password which are validated) and then have that "logged in" state transferred to another website which doesn't handle authentication for itself.
What you are describing is the Delegated Authentication model.
In this model, your application hands-off authentication to other systems which it trusts to provide information about users.
There are two well-known protocols which provide this mechanism:
OpenID
This is intended to facilitate users logging in with their own identity providers (Google, Facebook, Microsoft Account). It's a very good choice if you're running a public-facing website, as most users will already have an account they can log in with.
WS-Federation
This is intended to facilitate users logging in with identity providers which are managed by known trusted parties, such as partner organisations.
From version 4.5, the .NET Framework has built-in support for WS-Federation via the Windows Identity Foundation component (and is also available for earlier versions as a separate download). This automates the task of delegating your authentication to an Identity Provider.
It also provides components for you to write your own Identity Provider, should you want to create your own, but you shouldn't have to; you can find various existing implementations to perform this job for you.
The problem you're trying to solve is a very difficult one, especially trying to make it secure enough to be reliable. The good news is that smarter people than you or I have spent years working out very clever ways of doing this. You should use what they have done and not try to cobble together something out of Session state.
In the long-run it's best to let the smarter men do the hard work for you.

Users are being logged out of web site due to round robin load balancer

Our operator has implemented a Round Robin load balancer on our web portal and it seems to be causing some problems I can't get to the bottom of.
I'm able to identify which server we're on and as we navigate around the site we stay on server A. If I leave it for 5 minutes and try another page I'll get pushed to server B, logged out and shown the log in page.
I've got them to make sure the MachineKey in the machine.config is the same on both servers and I've tested locally that the session isn't being used - I can turn the session off completely locally and it still works. I've verified on both servers it is creating an ASPXAUTH cookie on the domain so we should be classed as authenticated on both servers - but keep loosing my authentication every time I change server.
Any ideas on what could be causing the logging out? I'm guessing it's my misunderstanding about how ASPXAUTH works.
Sessions are handled separately from Forms Authentication. There is a good explanation of this here.
The most common reason for Forms Authentication failures on load-balanced environments is lack of synchronization of the MachineKey element. You've stated that you've got the server operators to ensure that the MachineKey is synchronized, but have you verified this yourself in some way? Is this the case on ALL the web servers? From previous dealings with a couple of commercial web hosts, I've found that it is (unfortunately) difficult to take their assurances at face value.
Another thing to check is if the FormsAuthentication configuration (timeout, path, name, etc.) is the same on all of the hosts.
Are the patch levels the same on all of the hosts? You might want to see if the compatibility switch mentioned here is applicable in your situation.
Assuming that the hosting setup is correct, maybe you have initialization code on the page that logs you out if some condition is not fulfilled?
Try to take a look at the server logs and trace the sequence of HTTP requests involved during a failed page request. That might produce a clue.
Edit: This guide to troubleshooting Forms Authentication problems is detailed, and quite helpful: Troubleshooting Forms Authentication
Check for any other application functionality which depends on cookies. The web server on Server B will not recognize cookies that came from Server A. If any part of your authentication depends on cookies being populated, then that could cause your problem.
You have probably already ensured that the domain used for cookies is the same on all of the load balanced servers, but I thought I'd mention that. If the domains aren't compatible, then the browser will simply not send cookies to the server.

Categories