Hi, my name is Mykola Pidopryhora and I’m a Web and .Net software engineer at EGO. Recently I worked on a project where I was responsible for securing an ASP.NET MVC application. To solve this task I searched for answers on the Internet, but as it turned out there was no complete solution for this problem. So, I decided to invent my own.
In this post, I would like to share this ready-to-use solution with you, so you can save some time for a cup of tea with a cookie.
As a web development firm, sometimes we need to implement specific security rules, like user auto-logout, whenever a session is timed out or the user closed his browser. There are several approaches to implement such behavior and very little information about how it can be done.
I’d like to introduce you to one of the approaches that allow you to use your set of actions on a user’s browser close event. It may seem tricky and so it is. Anyway, in this particular case, it was the most fitting solution.
I tried to make the article in a guide style to keep it simple. Here is an example of how to implement a user auto log out in ASP MVC.
It includes handling the following scenarios:
- log the user out when a session is expired
- log the user out and run custom commands after a tab/browser was closed
- log the user out after navigating to a login page
- handle work with a load balancer
Use Session Timeout to Kick the User Out
Setting session timeout in web.config
In order for a user to be logged out after a session has expired, they should make a request.
Let’s add a bundle and some scripts for that
The following script will do one simple thing: it’ll start a timer with a timeout equal to the session timeout. When the time is out it will submit a logout form with the ‘session expired’ flag.
Let’s add a helper function that will allow us to pass the value from the server to the client script.
In our web application development company, we prefer to use use separate layouts for authorized and unauthorized site resources:
And here we use an extra function and bundles for the authorized layout:
This way we get a user kicked out when the session is expired. The server side will be also notified whether the user pressed the Log out button manually or has been kicked out automatically.
Implementation of User Kickout on Browser/Tab Closure for Non-Load Balancer System
The following approach may be used for systems that have no load balancer and use one place for sessions. In order to implement such application behavior, I will use the WebBackgrounder library, which you can find here.
Approach general overview: keep every user’s session in a collection and clear the sessions during which the user’s browser didn’t send the Ping request in time (when the browser was closed).
Let’s start from adding a job that will keep and handle sessions:
In order to keep a single sessionId per request let’s add Session_Start callback as well:
Let’s add the Ping action and the OnAuthorization filter into BaseController:
We also need to clear the session on user logout manually and inherit controllers from BaseController:
And finally let’s add a script that will send a ping request to the address that we have passed into it earlier:
Let’s make some modification in actions:
Now we need to add request filtering and disable browser cache:
Well, that should be enough.
You can play with timings of ResetPingStatusJob, session timeout, and pingActionInterval to get the user logged out after the time period you want. With current timings, the user will be logged out approximately after 30 seconds since browser/tab has been closed. This was the requirement for the project our custom web development company was working on.
But I’d like to add one more thing…
Let's Make a User Log Out When Navigating to Login Page
And update login layout with using bundles:
Using Application With Load Balancer
If you are going to use load balancer, you need to implement custom session storage provider or use the default session storage with an SQL job that will clear session with a task like this:
In this case, you don’t need to implement PingJob, which described above, but you’ll still need a ping action and session-ping.js.
Here is an example of such an MS SQL job:
One More Thing
As an outsource web development company, we know how hard it is sometimes to select a tech partner for your web project. You go through blogs of dozens of firms to figure out if they possess the necessary expertise and have experience in building your kind of projects. Then you consider lots of factors and even in the very end you’re worried if your choice was right.
To address this pain, we’ve come out with Product Plans, an easy way to get the most value within a limited budget and time. Each of our plans is carefully crafted and calculated to help you advance with your project and at the same time see us in action. And then, you can either continue working with us or take the feasible outcome of our work and put it to work with another partner (though that never happened yet).
And if you have any additional questions, feel free to contact us.