I have created a web page but i want to restrict only one instance of the page should be running at all times. The scenarios are given as below.
First time - User launches the page by URL and page loads.
User types URL again in another window and it should say that a page is already open OR refresh the existing page.
User closes the window and tries again - new fresh page will be loaded.
Additional Details : I have a database, user authentication.
Tried So Far : Set a flag in DB-->> This method how do i redirect the user back to the page which is already opened.
Any ideas to implement this.?
Thanks in Advance for your opinions and suggestions.
Perhaps you should use a cookie which expires when the user closes the browser. However, all browser instances may need to be closed.
First time, there is no cookie and http_referer does not contain the same domain. (set cookie now)
http_referer contains the same domain
cookie expires and go back to (1)
You should consider using cookies for this. Create a session-long cookie upon opening of the window and destroy it upon closing of the window. If a cookie already exists, you know the window is already open.
This of course relies on javascript and is easily got round. You can not use a server-side solution because it would be impossible to catch the closing of the browser window in order to clear the cookie.
Personally, I wouldn't try and restrict the opening of multiple windows but restrict the functionality available in each window. This approach would be much easier to control using a server-side approach, e.g. events fired in the window can be validated server-side.
Related
Today, our B2B web application times out user sessions after 6 hours of inactivity. If a user's session times out, the user is redirected to the login page, and then redirected back to the original destination after login (via a "returnURL" querystring parameter sent to the login page).
This works great for regular HTTP GET requests. But what if a user is in the middle of a long data-entry operation and then goes home for the night? If the user tries to submit the form the next morning, their changes are lost.
Instead, I'd like to enable a similar workflow for forms like we currently have for GET requests: the user clicks "save", the user is forced to re-authenticate, and (if login succeeds) then the form would be submitted. Another alternative would be to force a re-login, but instead of submitting the form, simply drop the user on the original page so that the user could try again to save changes.
All the data we need to submit is on the client-- it's not like we're storing data in the session that would have been lost.
Is there an accepted pattern to handle this case? Should I use a window.open popup window and close it after successful login? Use a jquery dialog overlaid on the page? Something else?
I know that login UI is often treated specially by web apps to reduce cross-site scripting risk and for other security-related reasons, so wasn't sure if there was a well-known best practice for this use-case.
One way to handle this would be to periodically save drafts of the user's work, like StackOverflow does. For cost reasons that's not practical in our case-- for now we simply want to make saving-changes workflows resilient to session expiration.
We're using ASP.NET MVC on the back-end if it matters, and jQuery on the front end, but my question is really more about security and programming best practices that I'd expect to be platform-neutral.
It would depend on the amount of data being collected, but a possible solution could be to save the page state to the browser's local storage using either "localStorage" or "sessionStorage". "localStorage" and "sessionStorage" are properties of the web browser that are exposed in Javascript and are supported in most modern browsers (Chrome, Safari, Firefox, IE 9+). "localStorage" holds data indefinitely while "sessionStorage" holds data until the browser or current tab is closed.
It may be possible to store everything needed about the page, redirect the user to log in, and then reload the page using the stored data.
Before redirecting to login:
if (window.sessionStorage) {
window.sessionStorage.setItem("firstName", $("#firstNameField").text());
window.sessionStorage.setItem("lastName", $("#lastNameField").text());
}
After retunring from login:
if (window.sessionStorage) {
$("#firstName").text(sessionStorage.getItem("firstName"));
$("#lastName").text(sessionStorage.getItem("lastName"));
}
I have built an ASP.Net MVC site using Forms Authentication for a client.
Recently, they have requested that an authenticated user be restricted to a single browser session. That is, if the user raises a new browser instance, or opens a new tab on the original browser window, that he/she be logged out of the original. They insist on the added security.
Does anyone know how I might approach this? Thanks in advance.
Personally, I would push back and ask exactly what security this is bringing. Maintaining state like this counter to web architecture and is only going to bring you and your users grief.
Here is what I would do if presented with this problem:
Store the username of the user in your database (i.e. LoggedOn table).
When a user logs on, check to see if their username is already present in the LoggedOn table.
If the user isn't already logged on, insert a row into the table with the username and the current time; otherwise present the user with a message informing them that they can only log into the system from one device at a time.
Include logic to expire and delete the rows in the table if a user's session expires or if the user logs out.
First a disclaimer: I'm no expert in web programming.
Perhaps you might try a system where every user interaction requires the submission of a random value that's been generated for that page (much like what's used for CSRF protection.) That key could be kept under the user's session information on the server, and if a page is ever requested without the correct key as a URL parameter, the session is invalidated. The URL from one browser won't work in another, either, since once a URL is gone to, the user's session key has changed. The only way for a user to transfer a session between tabs would be to copy the URL of an unclicked link and paste it in a new tab's address bar. Switching browsers would be even more complex assuming that ASP.Net uses a session cookie: the user would have to transfer the cookie from one browser to another. Going back would also fail, as all the links on the previous page, and the URL for the page, would carry an incorrect session key.
Also, for reference, I believe the US Gov't TreasuryDirect site works in the way you've described, though I've never looked at how they manage it.
Thanks, people for the suggestions. Each had strong merits, however I had to take a hybrid approach. I found an incredibly simple suggestion from this post.
I implemented table of active users as Karl suggested as well. This will give the client the ability of deactivating the user on demand.
Thanks again.
Think of it as one active view at a time instead of one browser or tab. Or convince the customer to view it this way.
You can always issue a unique cookie for the browser session (ASP.NET Session) and allow communication to the latest cookie issued effectively making only one session active at a time, and therefore rendering other open sessions (browsers, tabs, etc) useless with the app by disallowing them communication any longer or serving up an error page for them. To do so you have to recognize who the user is and authenticate them against your app. This is half the puzzle and will force the user down to use your app in only a single browser at a time on their machine.
The other part of the problem is to pare down the windows and tabs that are part of the same browsing session of that browser, to allow only one view to be active at a time. To do so you can issue a unique sequential ID to the viewstate of each page for postback to the server to uniquely identify that page apart from other pages sharing the same session state (whether that page be in a browser tab, a frame or new window, etc). Or a code of your choice that's traceable. You then know which page is posting back within the session and can disallow others or deactivate previous ones by, again, shutdown down communication in some manner or serving up an error page, etc.
A new browser instance or a new tab may or may not be part of the same browsing session depending on how the browser is configured. I believe, for example, IE provides a setting that allows the behaviour to be set of whether a tab opens in a new process or session or shares the session. You won't necessarily get expected consistency across browsers to rely on for this feature, therefore you need to take programming steps to reign it in, like those described above.
You can additional steps like disallowing the user to be connected from a different IP# at the same time.
I have an application that requires a user to login. Upon login, a key is stored in the database for that login session.
I am having an issue when the user does Ctrl+K because it opens a duplicate window, which is now sharing the key stored to the database. I redirect them to the login page when they open a duplicate, but they are still allowed to click 'back' and they now have two windows with the same key - this causes MANY problems in my application...
How can I stop the user from going back - or how I can force login again (which creates a new key and both windows would then be valid) on any new window?
Thanks
How are you detecting that they are opening a new window? When you redirect them, can't you simply set a flag in your database that indicates that their current session key is not longer valid? This way, they are really kicked out - and not simply redirected to a login page.
okay - found a different way to handle this using window.name.
Thanks anyway all.
I am using forms authentication with Asp.Net 4. At the moment when the users click on logout link, I clear the session and call FormsAuthentication.SignOut() and this prevents the users from going back to the site without a logging in again.
Now I want to kill the session when the browser or tab is closed. I tried doing this by handling onbeforeunload event, but I ended up killing the session after clicking any internal links.
Any ideas how I can do this?
You can't, but you can come close to.
The authentication cookies are session only, that means that delete by browser when the browser close. Maybe you do not close all browsers tabs, but if you close them all the authentication cookies are lost.
About closing a tab, you do not know if the user have other tab opens.
A possible solution maybe is a call every 10 seconds back to the server to keep this authentication active or not, and set the authentication to end up after 20 seconds. So if not any signal come back, the user have gone. This can be done using javascript. From the other hand this can not let the user logout after some minutes of inactivity, so you may need a combination of this logic with something else.
The best you can do is when your user explicitly logs out to also call Session.Abandon() to remove that user's session. But like others have said there is no way of knowing if the tab/window just closes without doing a logout in this fashion. The session will just hang around on the server until it expires.
I answered another question that had a problem with session being killed when the user edited the web.config on a live site. They were tracking users still being logged in with Session variables (dangerous). But came up with a solution (untested solution) that could help people here.
FormsAuthentication allows you to maintain a person being active and logged in indefinitely. But if they become inactive for e.g. 20 mins they will be logged out which is nice. But to have them logged out at the time the close their browser is not possible (wait for it...) as setting the timeout value to 0 would cause them to be constantly logged in then out again.
So solution : at the time you log a person in using FormsAuthentication you could also set a standard session variable cookie that will be deleted when they close their browser. This cookie would have non-identifying non-account related information. Just a simple "loggedIn:yes".
Now all your code would need to have on it's masterpage/materlayout is a high level call in the page cycle or constructor of the page cycle (or even a custom attribute) that would check both cookie and the user identity:
if(!HasLoginCookie() || !System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
// redirect user to log in page.
}
Basically if the cookie is removed when the browser is closed, you will redirect the user to the log in page.
Hopefully that helps (and works. As I said untested).
My UI prototype requires me to show the sites login info all the time. Either I should show the usual username and password textbox or "you are logged in as". The last bit don't have to be secure, as it's only info to the user, nothing I will use server side. But the first part should send secure to the server.
It seems that I would have to use https for all pages on the site then. I would like to only use ssl for the things that are required to be secure.
One way is putting the login information into a https://../login.aspx and show it on my mainpage as an IFrame.
One disadvantage I can see is that the user won't know that https is being used, unless they read the IFrame src in the source code.
What do you think?
Are you using the built-in asp.net login controls or do you just use two textbox controls?
You could use your own form tag (not runat="server") with the action attribute set to "https://..." and just use two html input tags and a button to log on.
Again this wouldn't show the user that there credentials are secure when logging in.
Because of some recently discovered SSL attacks, it is always preferable to also put the logon form on a https:// page. Otherwise a hacked can intercept the http stream and change your form action from "https://..." to "http://..." and then sniff the credentials.
Another option would be to take advantage of the PostBackUrl property of the Button control.
You would need to create your own login LayoutTemplate to take advantage of this though. You would then be able to add the secure scheme to the current page URL, and set the PostBackUrl property of the submit button to that.
This would have a similar issues to your iFrame solution (the user wouldn't see the padlock symbols), however you would have the advantage that you wouldn't be using iFrames.
Another issue using an iFrame is the affects that they can have on the page:
They are a separate request, but can cause a block on the JavaScript PageLoad event firing.
The login form would only postback within the iFrame, so you'd need to refresh the parent page when the user is successfully logged in to remove it.
Additionally to that, errors would be returned in the iFrame, probably not leaving you much space for displaying the form as well, etc.
You've hit the major problems. You want the login, which needs to be on every page to use SSL, but you don't want the entire page to be SSL.
This is more of a business decision at this point than anything else. Would you rather your customers feel more secure about visiting your site, or do you want the login information present on every screen?
If you need to have both, you may need to also look at making your entire site SSL.