Django File Access Security - django

I want to restrict access to all but a few selected files per a user, but if I type: /media/userdocuments/FILENAME django happily spits back the file for even users who aren't logged in. How can I integrate the permission framework to work around this?
Thanks!
EDIT: I realize that the django development server is insecure, so I guess the question is: How would I do that in a production environment with apache, lighttp, etc.

Use RewriteMap along with a script that connects to Django and verifies permissions, rewriting to a "disallowed" URL on auth failure.

Related

Authentication using Django’s sessions db from Apache

I have a Django application which I now want to integrate it with Kibana. So when authenticated users click on a link, they will be directed to Kibana. But this option should not be available to anonymous users.
My stack is Psql + Django + mod_wsgi + Apache. The solution I came up with was restricting access to Kibana via Apache, and authenticating users in Django before giving them access. This HowTo in Django website says how you can authenticate against Django from Apache, but that one uses Basic authentication. When I use this approach, even for users who already have an active session in my Django app, they will be asked to enter their username/password in a browser dialog!
I was hoping the authentication to happen using the current Django active sessions. I believe for that I need to use AuthType form and mod_session, instead of AuthType Basic, but it seems mod_wsgi does not support mod_session yet (as discussed here). I checked other WSGI alternatives as well (gunicorn and uWSGI), but couldn't find anything.
So my question is how I can Authenticate against Django session db? Is using mod_session + AuthType form correct? and if yes, what's the best way to achieve this?
Thanks a lot

How to get user name after authentication?

I built a website using Django and Apache. I have Apache LDAP authentication. How do I get the username after the user authenticate to the website? I want to get the username and represents it.
So you're using Apache LDAP Authentication. If you use mod_auth_ldap, see the docs here http://httpd.apache.org/docs/2.0/mod/mod_auth_ldap.html#frontpage. If you use
mod_authnz_ldap see the docs here https://httpd.apache.org/docs/2.4/mod/mod_authnz_ldap.html#exposed.
What the docs tell is that, when the user is authenticated Apache sets environment variable, that can be accessed from CGI script. Variable name varies depending on the version you use. Though Python uses WSGI, you should still try to get the variable as it's environment variable and should be accessible anyway.
In python to get access to environment variable:
import os
username=os.getenv["REMOTE_USER"] #will return variable value or None
if username:
pass
#process username here
See docs on this function here: https://docs.python.org/3.5/library/os.html#os.getenv
You can try to use this directly in your Python code where you expect the username. Or better use this code in wsgi.py in your Django project and if username is available add special header with its value, so that it will be available inside Django in request passed to Django views. But remember to strip that header before adding it, so if a malicious user forges the header it doesn't affect your app. For more information on this see https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/modwsgi/ and https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/apache-auth/.
Edit: Btw, there's a "How-to" for REMOTE_USER: https://docs.djangoproject.com/en/1.9/howto/auth-remote-user/
Edit: If you don't have any requirements for performing authentication with Apache, you might want to perform authentication in Django app directly, see: https://pythonhosted.org/django-auth-ldap/ and in example https://djangosnippets.org/snippets/901/.

how can i check that a admin user is logged into django website or not into NGINX

I want to see that admin user is logged in or not into nginx.conf file .
I need this for my specific requirement.
My Try :
I tried to fetch COOKIES into nginx.conf file.
but when admin is logged out so cookies are changed so i am not able figure out that if a admin is logged in or not.
As far as I know this is not possible.
Django uses encrypted cookies by default and stores all data in the session table in the DB (also encrypted). You could check if the user has a cookie set in nginx but you won't be able to verify if that cookie value actually means "Admin" or "random other cookie value".
Also unless you're using custom nginx modules to check the contents of the cookie you run the risk of someone managing to trick nginx into thinking the user is an admin when that is not the case.
I'm not sure what the use case is here but you could try doing something with the django middleware or looking for third party plugins instead of using nginx.
If you want to limit file access to a specific file, e.g. admin-only images/javascript/data files or such you could try the HttpAccessKeyModule for Nginx and just generate a custom 'url' for your admin to access them.
You can also try looking into: http://nginx.org/en/docs/http/ngx_http_auth_request_module.html and see about delegating the check to some part of Django which just returns Yes or No to nginx.
There might be another nginx plugin somewhere which you can add/enable for an admin user from within django. But this requires you to think the other way around. With django telling nginx the user is an admin. Instead of nginx finding it out itself.
Hope this helps you in some way.

Need one login for two different sites

I am tasked to create a web site using Django. It will be a 'sister' site to an existing Plone site. The same Apache instance will be the front end to the sites which allows me to use the same domain name.
However, the owners want the users to be able to log into one and still be logged into the other one.
How can this be accomplished?
Thanks! :)
Gut reaction is to use OAuth - see How to build a secure Django single signon between different sites?
Alternatively, have you tried this single sign-on app - http://code.google.com/p/django-sso/ ?
Also have a look on Django's documentation on how to implement your own authorization backend at http://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authentication-backend
My gut reaction is to use LDAP. Plone's LDAP support is a little rough, but it works. Does Django have equivalent or better LDAP support? If so, then I think you are off and running…
You can move authentication to SQLPASPlugin and use the same table for Django and Plone.
There are two problems here, shared logins, and single sign on. LDAP or SQL based logins will give you the first, but you'll still have to enter your password in both sites. You need single sign on to remain logged in across bpth.
plone.session 3.0 (part of Plone 4, but compatible with Plone 3.3 if you also add hashlib to your buildout) is compatible with Apache mod_auth_tkt single sign on. It should be simple enough to configure Django to use Apache authentication, or if you're not running Apache, wrap plone.session's tktauth.py in a simple wsgi wrapper. Use the Plone site's require_login script as the TKTAuthLoginURL.

Django Admin - Re-authentication?

I'm in a bit of a dilemma at the moment regarding Django's admin backend. The default authentication system allows already logged-in users that have staff privileges to access the admin site, however it just lets them straight in.
This doesn't feel “right” to me, and I'm wondering if it would be difficult to at least require a re-authentication of that same session in order to get into the backend.
Preferably though, it'd be good if the frontend sessions could be separated from the backend ones (though still using the same user objects), this would allow a clean separation of both parts of the site. Would this perhaps require two separate authentication backends? Would something like this be difficult to achieve?
Here's an idea: run the admin app on a different domain to the frontend. The cookies won't be valid in the other domain, so the user will have to log in again. All you'd need would be a separate Apache vhost and a basic settings.py that just has contrib.admin in INSTALLED_APPS.
You could probably implement a middleware that asks for authentication when accessing the admin site from a referer not in the admin site. It could log the person out and make them log back in, but even that wouldn't be necessary. Just require another password entry, and redirect them if it fails. It might involve setting a session variable, is_admin_authenticated or something.