I have to design a CMS where a set of credentials can only be used once. So if a user has logged in from his computer, no-one can login with his credentials from another location until that user logs out.
Now using the asp.net membership provider out the box, the IsOnline method returns a boolean that reflects the timeout window vs. the last activity date. This is not a viable option for me, because if the user just closes the browser after logging in, IsOnline will still be true. But his session will be destroyed(assuming he's not using Remember Me) so if he tries to log in somewhere else it will say "Sorry you still logged in".
Are there any hard and fast options for doing this..?
I was thinking of forcing the users to be "Remembered" so when he logs in a boolean "IsReallyOnline" will be set to true and vice versa when he logs out.. Although this option has it's limitations, (people turn off cookies, not logging out and closing the browser then sum1 else comes and browser to the site and he's logged in etc....) it seems like the most viable for now?
Any suggestions?
Thanks in advance
You are really asking for something that is outside of the remit of the web. The HTTP protocol is by definition stateless, meaning that at any one time; a server never need know if a client still exists. The newer/older implementations of web server programming languages (e.g. php / asp.net mvc) for the most part shy away from storing any state about connected/active clients.
Some things to ask yourself include:
How long may a user be 'active' on a page without causing a postback? Javascript based pages may allow for a user to interactively be using a page for quite some time before any kind of postback happens.
Will the users be going through a proxy or caching server? Multiple requests from 'different' users may come from the same machine in this case.
Will your application be running on one machine only, or maybe a server farm? You'll need to ensure that load balancing (for example) doesn't punt different users onto different servers allowing multiple logins.
How about a user legitimately using two different browsers on the same machine? Is this to be allowed?
One might suggest your problem here stems from trying to use the wrong technology given your requirements? Maybe writing a client application which uses direct connection to your servers would be more 'secure'? (Yes I understand this is huge hassles but if your one user / one logon requirement is absolute maybe you could explore this avenue?)
Oh alright, a web solution
For a http centric solution you could try a javascript timer making a request to your server every X seconds to indicate that the session is still active. As long as the browser is open and the network connection valid you should be getting these 'pings'. The session is kept open by the cookie passed by the httprequest.
You'll be able to code the 'ping' page to store the user details into either the application object or some membership provider of your choice then interrogate this provider whenever a client attempts to log in.
This will require a relatively short time-out on a session or some other mechanism to ensure that a crashed browser doesn't lock your legitimate user out for too long.
Please note: This will fail horribly if the user doesn't have javascript turned on (Don't assume that they will have!)
Fast Option: Store IsOnline as a session.
Check if session is true, then allow. If not, don't allow.
If user closes browser, he will be logged outas its in a session.
Related
I'm working on a C# MVC application where users submit applications to administrative users for review. Applications can be approved or denied by administrative users. My home page for administrators renders a list of submitted applications, and clicking on each application opens a new page where applications are processed.
My concern is simple: since the "Id" attribute for each application is a hidden html element on the admin "Process Application" form, it is possible that a user could modify the application ID and submit the form (in turn approving/denying the inappropriate application). I can get around this by using a Session object for "AppId" and verifying the AppId posted by the form is the same as the session AppId.
However (and this is the real problem), if I set Session["AppId"] = applicationId that session object can easily be overridden if the user was to let’s say attempt to process another application before submitting the first. Perhaps the admin user fancies their self a multi-tasker and opens two "Process Application" windows. Essentially, the first Session["AppId"] will be overridden by the second. This causes a problem on postback because now I can't validate anything based on Session.
While writing this, I realize I could add controls to prevent the user from processing more than one application at the same time. Is there an alternative approach though? Also worth noting, only admin users would have the ability to forge an application ID, which is unlikely because the Web-App is meant to help the admin users. Really I’m just looking for a best practice for these scenarios, as opposed to fearing someone will actually forge elements on my form.
Is my best approach actually storing an AppId in session, and preventing admins from processing more than one App at a time (so that the session object isn’t overridden)? It would seem so, but I’d love advice from the community.
PS: I realize this issue is similar to Secure way to stop users from forging forms. However, I think the biggest difference is I’m currently allowing users to process more than one application at a time, which prevents me from using a single session object for “AppId”.
I'd approach this from the "sanity & security" point of view. Users should only be able to change what they are supposed to change, data should [also] be validated on server side, and then you can disregard all forgery :-)
The best approach I’ve found is to check the AppId session object on page load. If it exists, then the user did not finish processing the original application (that scenario can be handled in various ways. I'll let you decide what is best, but you could probably redirect the user back to process the original application with an appropriate warning message explaining what happened). This is the only way I can think of to prevent the forgery of an AppId on the form using a single session object.
I have been given a task to sort out a bug in a SilverLight application, however my knowledge of authentication is basic at best so I am quite stuck and looking for help.
The issue is that if a user logs into the application, then opens another browser tab/window and accesses a URL from within the application, this is perfectly acceptable and the system works ok as far as we know. The problem arises when the user logs out of the application from one tab/window and then tries to continue to work on the other tab/window, in which case a variety of errors are thrown depending on what the user does.
We already have a timer in the application to detect connection issues with the database so I thought that checking that the user is authenticated here would be a good start, so I checked for AuthenticationService.User.Identity.IsAuthenticated, but unfortunately that is always true. So I researched and debugged my code and that property is actually set to false once the Logout method has completed, however this doesn't seem to be the case when I debug the application once the user has logged out on the other tab/window.
I have researched on the internet, but all the similar issues I can find are caused by something that isn't relevant, or that I don't understand completely.
The system uses an authentication class which is inherited from FormsAuthentication, but all the Login and Logout functions use the base WCF RIA AuthenticationService service methods.
Could anyone make some suggestions as what could be the issue?
When you log out basically what happens is that the server will destroy your session in the server memory/session state etc. If there is a new request from the same client the server will read the session id cookie and try to match it with one of the existing sessions. If this session will not be found then we will get the exception you are facing.
Having a SilverLight application this is basically a client application which will not send any request to the server until it really requires is ( Service call). I think you should send a log out message to all of your application instances to log out the user also on the client side everywhere else.
Maybe this links will help you
Can silverlight detect or communicate across browser instances?
Writing a javascript file from another javascript
What I am looking for is way / design to track a user / site visitor without the need for cookies or JavaScript as about 5% of users have one or both of these turned off.
What I would like to achieve is a unique reference for the user which can be captured server side in code.
I was thinking machine CPU / Motherboard ID but this information is hidden.
What information could you use / combine to create a unique hash.
I also need that ID to work across different sessions. Or maybe if the information is unique enough a way to do cookies/cookie type things across different browsers.
You could put a code in the url, this is how cookieless sessions used to work (maybe still do).
UPDATE: taking comment on, depending on your application and number of users you could consider giving each user a dedicated sub domain, or if subdomains are too tricky build it as part of their url. This depends on whether they need to login into the site.
You could look at doing something with client ip addresses but this would not work for everyone.
Are you sure the users really have Cookies switched off? It could be that users have persistent cookies switched off (the ones that write a file to the user's hard drive) and still have browser session cookies switched on. Browser Session cookies live in memory and disappear when the user closes their web browser, but normally this is enough for server-side Session State to work properly.
In nearly all cases where clients have cookies disabled, it's always persistent cookies only. The in-memory ones are still enabled and work fine, you can still track users, but only for as long as the browser remains open, this might be enough for you I don't know.
Update: I just noticed you said this needs to persist across sessions (as in user closing browser down and going back to site later). Have you looked at HTML5 storage options (LocalStorage in particular), it's a simple Key/Value store, and it's reasonably supported across browsers even versions of Internet Explorer.
After some more research aided by Rup and the ret of the comments on here, it has become apparent that there isn't a simple way to track a user across your site without cookies, But its not impossible.
Looks like the only way to truly achieve this is via browser finger printing, using all the information supplied back to the server to make a unique finger print of the users browser, this seams to work for about 95% about the same as cookies.
Browser finger printing at the moment seams like a workable approach but I feel there might be quite a large backlash from the general public / privacy groups if you where to go down this route.
For the moment it seems we are stuck with cookies.
So i have a custom CMS running under .Net 3.5 written entirely in c#. The engine is optimized to render for mobile devices, but also server to normal web browsers. It also supports cookieless sessions. Great...
I've chosen not to cache anything (including browser data) in order to control the rendering completely from data. This has been all good until lately.
The engine implements a basic login function that simply logs the user state within a session object.
The behavior is rather strange. User will click through the site no problem. Then login. The login will either go through successfully or just redisplay the login screen, suggesting a cached page being returned or redisplayed... If the login is successful the concurrent page hits will switch arbitrarily between logged in and logged out state... Also suggesting either the session state is not accessible or a cached page being returned.
I have debugged the hell out of the thing.... including using fiddler and the like. When debugging the behavior disappears.
Huh?
One of the sites running on the engine is http://www.wiseguy.mobi (sorry customized for South Africa, so you'll probably not be able to get the password Text Message)!
Ok, so i've been a dumbass...
The issue was related to the fact that my IIS application was running 2 WorkerProcesses. Thus InProc Session state would return different session object states when the user hits either of the worker processes.
This is why the SQL SessionState persistance has resolved it. Either was its set up rather nicely now, and the issues have been resolved...
is there a way to redirect a user when there are n people/sessions on a site. I have a requirement to redirect to a 'sorry we are busy, please try later' page if there are too many people currently engaging the site (this is to stop flooding a live business service that is behind the webpages). The ideal is that only new users (users not already logged in) are shown this page. I was going to just count concurrent logins but wondered if there was a better way to count current activity rather than login status being that most users might stay logged in for a while.
thanks in advance.
There are several ways you could do this.
I think the most obvious way would be to do this in IIS. If you are using IIS 6.0, you can do this by going into the website properties, go to the performance tab and change the connection limit to what you require. You can then customise the default IIS error message (I think this is classified as code 500).
Alternatively, you could do something when the user attempts to login to the website. You would need to have a mechanism to keeping track how many users are connected, one way of doing this might be to use the Membership provider, which allows you to track (count) how many users are currently logged in (presumably through some basic math on the timestamp values in the membership tables).
Finally, you could probably at a push do something with Ajax to keep telling the server that the a user is "still online", but I would do this as a last resort.
My money would be on the first option.
Hope this helps