How do I authenticate remotely in Django? - django

Basically what I'm doing is building a desktop application that needs to connect to a web server, perform some calculations, and then have the resulting values sent back to it. The calculations change over time, and also need to stay somewhat secure, which is why I'm not just coding them into the desktop application.
The issue is that only authenticated users should be allowed to access the server. So what I'm looking for is a way to log-in to Django from my desktop application (i.e. the desktop application will pop up a window asking for a username and password, which will then be sent to the Django site, used to authenticate the user, and if valid, will return the results of the computation. It also needs to work as a session (the user enters their password at the beginning and then doesn't need to log-in again until they close the desktop application, even if multiple computations are performed).
I think I need to use session keys for this, and perhaps the RemoteUserMiddleware described here but I really have no idea where to start as far as coding this. Any suggestions or pointers in the right direction would be hugely appreciated.
Thanks,
-Morag
P.S. If this is important, the desktop application is written in VB.NET.

Interesting. I've never done anything like this, but here is, what I assume, is the basic idea:
1) Get a good view of Django sessions; the basic idea is:
One logs in using the django auth framework login service
Django will create a session for you and handle all the difficult stuff
Django returns a HttpResponse with a sessionid cookie. You will need to send this back with any request following to identify yourself and 'operate within the session'.
One logs out using the django auth logout service and the session is destroyed by Django.
2) Now, the rest is relatively easy.
Setup django urls.py with the appropriate urls for login/logout + computation service
Execute a post request to the login service with the appropriate parameters set
Catch the response, extract the 'sessionid' cookie and save it somewhere
On each subsequent request, include the sessionid
This should get you started. Good luck!

Related

Session Hijacking in Django 1.7.7 and python3

I have developed a small application for submitting some data to database server(Oracle 11g). When we are reviewing security of this small application, we observed as follows:
1. We have deployed django with https and all secure configurations like Secure Cookie and Secure Session, No Cache, etc.
2. Using BURP tool for this sample review
3. We have created two different user in this system say Normal User and Admin User
4. Opened 2 browsers(Mozilla and IE 11), On mozilla we login with Admin user and captured session id using burp tool.
5. On second browser we login with Normal user and replaced session id Normal User with Admin User.
6. whoila......On second browser, I got Admin user access by just changing the session id
I have used default session backend for this application.
I would like to know whether this is flaw in django and how to resolve this issue..
Thanks in advance
This is an inherent risk of using session-based identification. It's called session hijacking, and if you search for that term you will find lots of information.
Mitigations generally have one of two goals: making it harder to steal the token, or making the damage less severe if it is stolen. In the former camp are techniques like using HTTPS and SESSION_COOKIE_HTTPONLY. In the latter are things like limiting the length of a valid session (SESSION_COOKIE_AGE). In the end, though, it's difficult or impossible to stop someone from impersonating another user if they get their token, since that's the very thing that establishes identity.

Send a post request to server

I am fairly new in web development and I decided to handle a user's availability to send a POST request to server. However, I do not know even whether it is possible or not but when a user close my Django site without using logout button (For example close the browser or tab), in order to understand the user is offline or online, I want to send a request to server. As a result, when the server does not get an answer from the user for a while, it automatically logout the user.
Can you tell me is it a good way to handle a user's availability and first of all is it a realistic solution? If it is, can you suggest me a document or example that helps me please.
I agree to to the answer of #Mounir. That's not related to django, if you want to know when a user is "disconnected"(close the tab or window) you need to use javascript, in concrete you need to use Sockets.
I recommend you this ones:
http://socket.io/
https://github.com/centrifugal/centrifugo
I'm using centrifugo for one project right now. In concrete, for chat and inbox messaging. It's very simple to make it run with Django.
Greetings
For logging out user you can use the Session expiration, but for all other staff you want to achieve I don't see any thin really related to Django itself, everything depend on your requirements and is more Browser/javascript related than Django.

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.

Django CSRF protection for mobile apps and chrome extensions

I have done a few mobile apps using django as my backend, and now I am working on a chrome extension. I want my users to be able to send POST requests up to the server using the app/extension but is there a way to do it without first asking the server for a CSRF token? It just saves the app from making two requests every time we want to submit data. For example, I want to update my profile on my social media app or update a wallet from a chrome extension. It would be nice to open up the profile view input the data and push it to the server. It's less sleek if I have to open the profile, then wait for it to grab a token from the server and then I can submit the data. Is there another way to do this? Or am I stuck making multiple requests every time I want to submit data?
Also, a little clarification, CSRF prevents sites from submitting forms with user's data. But what is to stop me from making a site that uses ajax or something to grab the real site and steal the CSRF token and then paste that into my cross site request form? I feel like there is a loophole here. I know that I am not quite understanding this all the way.
You can, and should, make any API endpoint CSRF exempt.
Django offers the csrf_exempt decorator for exactly this, see https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.csrf_exempt.
Also CSRF is intended to prevent unintended actions being performed via GET request forgeries. It is not intended to make it impossible for an automated system to submit forms, there are captchas for that.
As for what prevents you from using AJAX to grab the whole site and extract the token is something called the Same-Origin Policy. This is implemented by the browser and prevents any AJAX call from returning data when the target of the AJAX call is a different domain without the correct headers set. (I'm not entirely sure what sandboxing is applied to chrome extensions concerning this). As such it will, or at least should, fail to get data via AJAX for normal websites, e.g. a profile page. If you want to interact with third party websites you should look into whether or not they offer an API.

django and backbone.js authentication

I don't understand how you handle authentication when using django and backbone.js.
Lets say I have an app where users can sign up / sign in. Normally in django I'd just use the #login_required decorator with my views to test if a users is authenticated or not. Since backbone is RESTful and uses something like json to communicate with the server, it's my understanding it doesn't have a concept of being logged in.
So how do I create an django backbone app that uses django's auth system so I can still take advantage of permissions, groups and session based auth.
You may find it easier to keep your login and logout code in django normally, and only go to a Backbone-based template once the user is logged in. Many sites work this way.
You will also want to watch for 401 errors coming back from the server when you sync, since this can mean that the user's session has expired. (I assume django sends these.)