Managing multiple accounts in one session with multiple tabs open - coldfusion

Scenario:
I have an administration-application which manages the user accounts for another application. Now I would like to place an user-specific-link (e.g. Click here to login with user1) in the administration-application allowing the admin to directly log in with the user in a separate browser window or tab (target="_blank").
Problem:
When the admin clicks two or more links and opens two tabs with tab1=user1 and tab2=user2, the last clicked tab overwrites the session-variables of all other tabs. Sure... that's how sessions work, but I wonder if there is a way to let the admin manage multiple user interfaces with one session in multiple tabs? But I don't see a possibility to identify a specific tab in the browser so that I could say "in tab1 is user1 and in tab2 is user2 logged in ...
Question:
Has anyone done something similar and likes to share the basic idea of solving this?
EDIT:
One possible solution could be to add an parameter to the URL with the userid and hand it through to every page, right?

As your edit points out, the way to do this is with a url variable that specifies who the user should be.
There are a number of security issues with this approach tho.
I'm assuming that your initial link is doing some sort of security check to make sure that the initial "log in" of the user is an authorized request. You'll need to do a similar thing for this method. If your initial request is something like http://example.com/page.cfm?userid={id}&authtoken={encryptedtoken} I would then put that userid into the session scope as a valid userid that the admin can impersonate. The more links they click on the more users they can impersonate. On subsequent requests you check the requested userid against the allowed list in the session and either allow or deny the impersonation.
You'll also need to update all the links on the site so that they include the userid in them. The easier way to do this is to cheat and user jQuery or such to rewrite all internal urls with the userid appended. You would conditionally include that javascript based on the above check.
Lastly you'll likely want to prevent these urls that include the userid from appearing in search engines, if it's not a fully locked down site. You'll either need to use canonical urls to remove the userid, or set x-robots headers to tell search engines not to index the urls where the userid has been specified; or both.
That's the most primitive method of getting different "sessions" for multiple users in the same browser. However you'll then bump into issues if you're using the session scope for anything meaningful, because each tab will try overwriting the other. You'll need to overwrite the normal site session variables on each request, or you'll need to create different structures in the session scope for each userid that is used. How much of a problem this is depends on your application.
It's a do-able thing, but probably a lot more work then you were hoping for.
The other option is to get the admins to use Google Chrome with multiple profiles and copy and paste the login url into different profile windows. A slight inconvenience for them, but a lot less work for you.

Related

Tracking unauthenticated users in Django

I need to track unregistered users in my Django website. This is for conversion optimization purposes (e.g. registration funnel, etc).
A method I've used so far is using IP address as a proxy for user_id. For various well-known reasons, this has led to fudged/unreliable results.
Can I sufficiently solve my problem via setting a session variable at server-side? An illustrative example would be great.
For example, currently I have a couple of ways in my head. One is doing request.session["temp_id"] = random.randint(1,1000000), and then tracking based on temp_id.
Another is setting a session variable every time an unauthorized user hits my web app's landing page, like so:
if not request.session.exists(request.session.session_key):
request.session.create()
From here on, I'll simply track them via request.session.session_key. Would this be a sound strategy? What major edge-cases (if any) do I need to be aware of?
Cookies are the simplest approach, but take into consideration that some users can have cookies turned off in their browsers.
So for those users you can use javascript local storage to set some data. This information will get deleted once you close the browser, but it's ok for funneling purposes. Still others can have javascript turned off.
Another approach would be to put custom data(key) in every link of the page when generating the template. in other words you would have the session_id stored in html page and send through url parameters at click. Something similar happens with csrf token. Look into that.

Django Multiple concurrent logged-in accounts

In the context of a e-health related service, the end-users (health operators, doctors and physiotherapists) working in the same physical environment and sharing just one client PC to interact with my backend, asked me to provide them with a mechanism to quickly switch among different accounts (security is not a concern most of the time because they are used to work within a LAN but, occasionally, they might work from remote clients, so I must keep an authentication/authorization backend in place). They would log in just once and then, before using the web application, would select their logged-in account from a combobox (sort-of).
The UI model might be the same as in GMail where it's possible to keep multiple logged-in user accounts and switch between them through the account selector in the top right corner.
I'm no django-authentication expert, so I am not able to even tell whether this is possible in the context of a django based app.
Does anyone know of any ready-made app/middleware to get this done? Or maybe point me in the right direction if I have to extend or modify existing code?
Thanks a lot.
I haven't looked for any existing solution for this, so this is how I would go about it from scratch.
You'd need to add storage to the user session to hold multiple users. Currently it looks much like:
{'_auth_user_backend': 'membership.auth_backends.MyCustomAuthenticationBackend',
'_auth_user_hash': 'e2c8ecf1e7ecdbd<snip>',
'_auth_user_id': '3806'}
and I would add an array to the session:
logged_in_users = [{'_auth_user_backend': ... }, {}, {}] # one auth dict per user
Then when you "switch users", edit the session object to move that user's auth details (id, hash and backend) into the top-level ones in the session.
You'll also have to write a custom login function that stores the login into the logged_in_users array, and takes out the bit in the current login function that flushes your session if the key is the same as the session of a different logged in user. Similarly, you'll need to think what happens when you logout.

Django set django session cookies programmatically

I am creating a saas, software as a service site with django.
Due to the project requirements the users are inside schemas/tenants, for that im using the fantastic django-tenant-schemas app, one user can have accounts inside different schemas (they share username and password) ... i want to let the user move throught the different schemas they are in more or less freely ... for that i have created a view where the user can select on what schema he wants to be on.
When i use an application wide cookie session that is when i have the cookie setting as ".domain.ext" (django documentation) that works fine but its NOT the behaviour we really want for our application.
What we really need is to be able to have different versions of the app on different browser tabs.
So we have to set the cookie configuration to "domain.ext", then everything breaks because the original view is on one tenant and the next view (where the just logged user really belongs) is inside other tenant then the old cookie is deleted.
So the question is how can i programmatically set the cookie correctly on the new view so the user that really belongs to that tenat is still authenticated.
Or is there any alternative approach we could use for that? Any examples?
EDIT TO CLARIFY as demanded:
Person A belongs to 2 schemas SH1 and SH2 on both of them he has the same username and password.
On every password change the password hash is replicated on all the schemas they belong to so they dont have to remember specific passwords or usernames.
When the person is logged on SH1 the url will be sh1.domain.com when he is logged on SH2 the url will be sh2.domain.com
So lets say the person is now logged on schema SH1, he decides to switch to schema SH2, to be able to do that i need the user to still been authenticated so that view has to be on the SH1 schema, but then its redirected to the new schema force authenticating the user but since the cookie is set as domain specific (default django behaviour) when the user lands on the next url sh1.domain.com/whatever the previous cookie is deleted and thus he has to log in again to be able to access.
If I'm understanding correctly, you want the ability to have the behavior of a cross-domain cookie, but without actually using a cross-domain cookie.
The immediate answer that comes to mind is "well, use a cross-domain cookie". This is pretty much the vanilla example of a situation where you'd want to use use a cross-domain cookie. Engineering a complex solution so that you can avoid using the simple solution never ends well :-) Unless there's some other constraint in play that you haven't revealed, I'd start by questioning whether you shouldn't just be doing this the easy way.
However, assuming there is a good reason (and, frankly, I'd be interested to know what that is), the problem you're going to face is that browser security is essentially trying to stop you doing exactly what you're proposing. You want to know, from domain SH2, whether something has happened to a cookie set on domain SH1. That's exactly the situation that cookie security policies are designed to prevent.
The only way you're going to be able to work around this is to have a third party that can share knowledge. When user A logs into SH1, you do password authentication as normal - but you also post a flag somewhere that says "User A is now on SH1". When A logs into SH2, you post the corresponding flag. If A goes back to SH1, you check against the central source of truth, discover that they're currently on SH2, and force a login.
You probably could do this by manipulating cookies and session keys, but I suspect an easier way would be to use an Authentication backend. What you'll be writing is an authentication backend that is very similar to Django's own backend - except that it will be making checks of cross-domain login status against the central source of truth.
How you implement that "source of truth" is up to you - an in memory cache, database table, or any other source of data will do. The key idea is that you're not trying to rewrite cookies so that the same cookie works on every site - you're keeping each site's cookies independent, but using Django's authentication infrastructure to keep the cookies synchronised as a user moves between domains.

In Opencart, is there a way to restrict access to a page so that only people who are logged in and in a certain group can see the page?

Is there a way to restrict access to a page so that only people who are logged in and in a certain group can see the page? I really need help with this. It's for a big client and I don't want to turn it down!
Here's how it would work:
Customer is given a link via email that I will manually send out.
That link is to a page in the store. In order to see it they must log in with their account. And if they are apart of the right group, then Bingo, they can see the page!
I will have 3 groups total and multiple pages. Each page will be branded for the user which is easy. I just need to be able to send out a link to a page and only people in "GROUP A" who are logged in, can see it.
If you want to restrict access to default pages in OpenCart, you have to create a pretty simple VQMod. It should add a checkup in an common controller file (header.php is the best).
First of all, there's a standard isLogged() function in system/library/customer.php, commonly used like this:
$this->customer->isLogged();
You can also easily get customer info - id, group ID etc., using standard functions:
$this->customer->getId();
$this->customer->getCustomerGroupId();
Add these checks to index() function in catalog/common/controller/header.php and redirect on fail/success:
$this->redirect($this->url->link('information/yourpage'));
Of course, to implement all this you should know, how to use VQMod.
I'm almost 6 years late, but in case someone else needs this, there's a module here: https://www.opencart.com/index.php?route=marketplace/extension/info&extension_id=27897

In Django, disable #login_required for search engine spiders

I'm looking for a clean way to let search engine spiders bypass #login_required, viewing pages which typically require a logged-in user. I could write middleware that would automatically log search engines into a dummy account, but that's not exactly what I'd call clean. Any suggestions for a better solution? Thanks.
Don't do this. This is 'cloaking', and can get you banned from Google's index.
Cloaking refers to the practice of presenting different content or URLs to users and search engines. Serving up different results based on user agent may cause your site to be perceived as deceptive and removed from the Google index.
Cloaking: http://www.google.com/support/webmasters/bin/answer.py?answer=66355
Instead, you need to implement Google's First Click Free solution. In this setup, the first click from a Google search result is able to see the full content, subsequent clicks are trapped. This can be done on a referrer basis, or a cookie basis. You can read more about First Click Free here:
First Click Free: http://www.google.com/support/webmasters/bin/answer.py?answer=74536
Why would you want to do this? If search engines can see the pages, then anyone can see them without being logged in, because the information would surface on the search engine's results page. In any case, the only way to identify a spider or bot is by its user agent string, which is trivial to spoof.
I don't get it. in "#login_required" you have an important word: "required". if it's "required", it's for a good reason. It means that, in order to see the webpage, your credentials are mandatory. Because the content is private, secret, etc.
If you want to make your pages to be available via search engines, you have to make them public, and thus, login is not required anymore. And so, your view should not be protected by the #login_required decorator.
Maybe your problem lies beyond the availabilty of your pages. Maybe your content is actually made to be public, and your views should not be protected by this decorator. Maybe the only thing you need is to load the public part for every user (logged or anonymous) and eventually load the private bits if your user is identified.
Otherwise, leaving a backdoor for spiders is definitely a bad idea, because your private content won't be private anymore.