I have a Grails based web app which uses Spring Security to handle user logins etc. I have hit a bit of a block and am hoping the more experienced might be able to point me in the right direction for a solution.
The application has the concept of messages which can be sent from user to user to provide a instant messaging feature. There is a timed Ajax call that is present throughout the system which is used to alert the user of any new incoming messages.
My problem is that since I have implemented this, each time the ajax call is performed, of course the users session is being refreshed, therefore never timesout. So a manual 'log out' is the only way they can log out, whereas before expiry of a session would redirect them to the login page.
Does anyone know how I can still accomplish automatic logouts whilst still have the timer functioning?
I'm hoping I can set up some kind of filter with spring security, or perhaps there's an annotation I can use on the periodically called method to instruct it NOT to refresh the users session.
As always any help & comments are appreciated.
Thanks to Long for pointing me in a different direction with his comment, I believe I have now a much better, more intuitive user friendly solution.
Rather than trying to change things on the backend, I am using a little jQuery script which is very easily configured and fits in perfect with my app which already uses jQuery and the jQuery UI.
After a specific period, a jQuery dialog pops up, modally dimming the background and informs the user due to inactivity they will soon be logged out. A progress bar is displayed which reduces until it is empty at which point if the user hasn't click my 'Continue Working' button, then I change the window location to the spring security logout controller URL, taking them back to the sign in page. It works beautifully and is very easy to configure.
The instructions can be found here : http://kenbrowning.blogspot.co.uk/2010/04/are-you-still-there.html
Kudos to Ken Browning for his library.
Related
[Disclaimer: I'm not sure if this kind of question is accepted here as it is about a piece of software deployed already. Rest assured I didn't drop any confidential information. Also do tell me if I violated any rules in SO by posting this so I can take it down immediately]
I have a working Learning Management System web application and I recently received a bug report about a button not showing. After investigating, I have proved that the user was not using the web app as intended. When taking an exam, he was opening multiple tabs to exploit the feature that informs him whether the answer was correct or not. He then will use this information to eliminate the wrong answers and submit all the right answers in another tab/window.
I'm using Rails 4.2. Is there a way to prevent multi-tab browsing? I'm thinking like if a user is signed in and he attempted to open a new tab of the webapp, he should see something like "Please use one tab" and all the features/hyperlinks/buttons are disabled.
Here's a screenshot of how I proved he was using multiple tabs. Notice that there are multiple logs of the same attempt # because the current implementation allows saving a study session and resuming later (this is the part that's exploited). The opening of multiple tabs searches for the most recent attempt session and continues from there. This is also the reason why most of the sessions don't have a duration value -- the user only finishes a study session for one tab (by clicking a button that ends the study session). The system cannot compute for the duration because the other sessions don't have an end timestamp.
-
This is what a single-tab user looks like:
This is more of an application misuse issue more than a bug.
You should add protection not only from multi tab, but for multi browsers aw well, so it can't be purely FrontEnd check.
One of the solutions could be using ActionCable to check if a user has an active connection already and then act accordingly.
Another, for example, generate a GUID in JS and pass it with every answer. If its different from previous answer, it means user opened a new window.
But of course the solution would depend on your current architecture, without knowing how do you currently organise client-server communication it's hard to give exact and optimal solution.
I found an answer here. I just placed this js in the application view to prevent any extra instance of the website.
Thanks for everyone who pitched in.
We develop accounting system on a web with ASP.NET MVC and encountered this problem - if user is in the middle of the work and somehow manages to close browser all work is gone (and users are not geeks at all it did happen and will happen). Especially problematic at Chrome in Windows after they removed warning of closing tabs from philosophical reasons so now it will just shut down. We would like to be able to somehow catch this behavior. Also even when Firefox for example has warning that user is going to shut down his tabs - simple clicking the checkbox will remove it all again. So is it possible to keep track of this action to prevent user accidentally closing browser and lost all the work? Or is it even possible to do for example in Chrome? The solution would be simple warning window but it needs to show basically everytime if closing while our web application is alive. We don't want to keep session alive after closing browser for obvious security reasons. Also - it should work at Chrome, IE and Firefox. Thank you for your help.
you can try the below code:
window.onbeforeunload = function()
{
return "Are you sure you want to exit";
}
If your front end is using MVVM such as AngularJS or Knockout, or any of the other popular binding libraries, consider a different approach to preventing the user from quitting the page.
In a client-side interval, serialize your view model and store it in local storage.
When the save/exit condition for the current page is met, clear the local storage.
If the page is loaded again, and there is something in local storage, this means that on the previous session, the browser was closed before saving - so deserialize the local storage object back into the viewmodel (use a unique key per page) - you can combine this with some UI that tells the user that their previous state has been restored, click ok to continue or start over to start again (which would reset the viewmodel)
I should add that you'll have to watch out for multiple simultaneous tabs, so you may want to work around this by making the key unique somehow, e.g. creating two invoices simultaneously.
This essentially provides an auto-save but client-side only.
You can combine this technique with using window.onBeforeUnload as per Tejinder's answer, but as you cannot style the "unload confirmation" prompt, providing an auto-resume is a much better experience.
We have some sharing elements of our application where we embed logging IDs into the URL's that we share out. When a user clicks that URL, we add a record to our database so we can hopefully follow them throughout the registration process. We've found that if you reset your browser and go to the link the first time, there is no session info from the controller. However, all subsequent requests then have the session. It's almost like it's getting created after the first request.
We attempted to log it via ajax on the view, but this is cumbersome in all the places we want.
Anyone know what sessions wouldn't be available in the controller on first access for a new uesr?
I think you might have code in the wrong order. You must have the session creation before any logic can my applied to it.
Hope this helps.
We are looking at setting up an internal web application (ASP.NET MVC) as a kiosk for the employees that don't have a dedicated computer. We currently do not have this kiosk setup. Each employee will have their own login to look at some basic payroll information and request leaves of absence. This same web application will be used by the office workers with a dedicated PC at their desk.
I am going to go out on a limb and say that no matter how many times we tell the employees, the employees will not click log off when they walk away from the kiosk. What would you do to help prevent this from happening?
lets try to fix the users instead of the code :) , i guess that your log out button is like the one here on stackoverflow. its a little text link "logout" some where in the upper right corner. thats perfect for people who use webapps day by day and are aware of the fact that they need to logout before someone comes along a does havoc to thier facebook profile, but less tech savy users wont think of that and walk away.
you need to the get the attention of your users to this logout-button and teach them that logging-out is a good thing.
try the following
give the logout button more visual weight then usally make it bigger, make it a real button instead of a textlink and even change its color to something more alerting (red, orange, ... whatever fits your ci)
if they dont loggout, use the session timeout and some javascript the refresh the page after any amount of inactivity, but also set a flag that this user has not logged out after his last visit. that way you can greet him on his next login with a nice confirmation dialog, and tell him once again why logging out is so important and where your logout-button is located.
The naive solution would be to enforce a timeout. If there's no activity from the user within a certain time limit (say, a minute or so), log them out. Of course, this won't prevent someone from walking up immediately after an employee is done and seeing how much money they make.
ATMs handle this, I think, by timing out after a minute or two, which isn't super-secure but at least offers some minimal security.
If the employees have any kind of RFID card or other security token, you could require them to put it in a reader slot, and log them out whenever the card disappears. Handling this within a web app, though, could get complicated.
The simple way is to use a little javascript.
Just have it set to something like 30 seconds of inactivity. If the user hasn't clicked on anything have the javascript send it back to a login page.
Here's a link to get you started.
Assuming you've already thought of the obvious (aggressive session timeouts, non-persistent authentication cookies, etc); how about a bit of an "out there" suggestion?
I'm not sure how do-able this would be with a web-based interface; but what about using some form of IR sensor with a usb/serial interface and an API you can tie into? This may make it possible to invoke some form of "logout" operation when someone walks away from the kiosk.
Perhaps someone has a better suggestion for external hardware, but this was the first thing that lept to my mind as a out-of-the-box approach.
I found a jQuery version that seems to work quite well. I'll start by using that and see how that goes.
we've implemented a system similar to the one described in this other SO post. Basically, if the user doesn't do anything for 14 minutes, we prompt them that they will be logged out. If they click on "keep me logged in" we do an ajax request to keep their session alive, otherwise, they are redirected to the logout page after a minute.
It works pretty well, and is inline with similar systems employed at sites like mint.com and bankofamerica.com. The only problem is that our application's users tend to have multiple tabs open to refer back and forth to different pieces of data. So the problem is that they may be actively working in one tab, but then the other tab times out and logs them out. This causes an abrupt session timeout for the user when they were not expecting it. btw, mint.com has this same issue.
So I was wondering if anyone had any ideas to combat this?
I have one idea, each request could set a "last active time" cookie. Upon auto-logout, the server could check this last active time and if it's relatively recent, avoid logging them out. The manual logout would of course ignore this cookie so if the user wants to log out he can do so at any time. However, I'm afraid that this may be exposing some sort of security risk that I'm not able to see at this point. Thoughts?
Before showing the pop-up, ask the server how long ago the user has done his last request.