Going about Implementing Authentication/Authorization using CouchDb as backend in Django - django

I need to store both authentication and authorization information in couchdb. I've used a similar method to this for implementing authentication. However, what do I need to implement authorization for users. I need that certain actions be called only by specific users. Will using the user_passes_test decorator be a good idea for this?
I am also looking to move the session store to a separate couchdb instance. Will this be a good idea? Can anyone give me pointers/examples on how to go about this.
I am new to both Python and Django.

To answer the first part of your question, all you need to implement is the "authenticate" method of your custom authentication backend. The Django docs have some decent examples of how you could implement an authentication backend.
In regard to your permissions question, it depends on the exact details of what types of permission checks you need. If your permissions model fits well with Django's existing permissions system, you can make make authorizations decisions based on data in couchdb by implementing the optional permission bits in your custom authentication backend. Again, the Django docs have details on how exactly to do this.
As far as the session store, I don't know enough about CouchDB's performance characteristics to say if you need to store session data in a separate instance or not. What I can tell you however is either way, the way you use a CouchDB instance as your session store is to use a custom session engine. With a quick look around, it looks like django-couchdb-utils can provide you with a session engine that you could drop in without too much work (might also have some other useful bits for you).

Related

How does token based authentication work?

I implement a web application (with Python+Django - to the extent that matters). Users can log in normally with username and password, but in addition I want to provide an API which users use to script the interaction with my site.
For the API authentication my plan was to do something like this:
In the database I create table with 'tokens' - i.e. random strings which point to the user database.
The user gets a token string.
For every API call the user passes the token string along with their request
In the API implementation the code:
Verify the token.
Log the correct user in and execute the API function as the user matching the token.
Log the user out again.
Return the result
Does this make sense? On the one hand it seems very simple - on the other hand it feels quite homemade, something I have heard is not recommended when it comes to security related topics?
I would wholeheartedly recommend looking at django-rest-framework
https://www.django-rest-framework.org/
It literally does all of that and more!
Nope, not a sales person, just a developer :)
It handles quite literally any use case you can think of, and I would be happy to discuss at great length any its not suitable for.
It handles:
Authentication
Parsing
Encoding
View or object level permissions
Object serialisation
Object creation
Object deletion
Automatically generated documentation
Several authentication methods, including custom managed methods
And a bunch of other stuff that makes writing API's in Django much easier
All in all it supports most if not all use cases.
EDIT
It is worth noting that there is a very good reason DRF has short lived access tokens. That is because of security.
Let's say a malicious actor gets hold of your short lived access token, thats a lot better than a "long life" one as you described.
It's worth weighing up security and ease of access, security and protecting your users should always paramount.
Futhermore, I would recommend taking a look at DRF Knox, which is recommended in the authentication section of the DRF docs:
https://github.com/James1345/django-rest-knox

What is the correct way to deal with "Logging In" for an app written against RESTful web services?

I am in the process of building a RESTful API for my application. There are very few services that are public and the rest require authentication and authorization.
To be clear, my question is NOT about authenticating web services. I have already decided to send an HTTP header with an access token provided by the server. The reasons for this include:
Creating a "session" that can track the user activity
Timeout access tokens after XXX amount of inactivity
Track user behavior patterns for each "session"
So far, this approach is working fine. I am interested in any design guidelines for providing a "Login" service. I don't want to just authenticate a request, but I want to track usage of the web service against a "session".
In addition to "session" tracking, we have requirements that require that we track failed login attempts and take appropriate action after XXX number of failed attempts as well as password expiring and email address verification before authorizing, etc.
Specifically, I am concerned with the best way to design the URI's for this. One option would be:
/api/authentication/login?username=UN&password=PW
That could return the access token to be used in the header for secure service calls. Is this a good approach? Is there a better approach? Is there a better patter to use for naming the URI?
My biggest problem is that the URI is not purely sticking with the "URI's should represent resources" approach. End the end it is probably not a big deal, but I am wondering if there are better ways.
Thanks!
Often, RESTful APIs like to be stateless. That means that the API itself doesn't care about keeping a session, and doesn't.
What you do is authenticate 1 time, and then get a temporary key. That key eventually is no good anymore because the key has information in it about when it will expire.
Also, since these large APIs are built on message queues, they know timestamps for each action. and they can basically keep track of activity.
So, in RESTful API design, you often have scenarios where your URL has resources in it, and then there are all sorts of additional things that need to be set.
A good rule of thumb is to hide the complexity behind your ?. A typical use case of this philosophy is where you have a bunch of filter options on a get request of /some/resource. How is this relevant? Well, if you remember that its not a mortal sin to decorate your resource based API with other stuff occassionally, then you can treat other scenarios similarly when you feel like resourcefulness may be in question, but essentially you still have RPC-ish endpoints that need to exist to make your API fully functional for your needs. Or, of course, you can just arbitrarily set certain HTTP verbs to equal those things.
If you want to extend your resources with additional functionality, try to stick to the resource structure in your base url of the call, and then decorate it with your one-off needs.
Resource: /api/authentication
With modifier: /api/authentication/login
With data: /api/authentication/login?username=UN&password=PW
Its not so bad. But again, if you wanted to go completely restful, you could say something like this (this is pure conjecture, you need to decide these things for yourself):
Get logged in status - GET - /api/authentication/:id
Create / Update logged in status - POST / PUT - /api/authentication(/:id)
Log out - DELETE - /api/authentication/:id
... or you could have omitted the :id route and just hid that information in the body of data appended to the call, aka hiding complexity

object-level permissions django

How do you ensure that a User can only edit objects they've created? What's the best way to set this up?
I'm using django-rest-framework and wondering if there's a way I can restrict users from viewing/ editing objects they don't 'own'.
class Video(models.Model):
owner = models.ForeignKey(User)
...
So User 'x' should only be able to edit videos in their owner_set.
Presumably you have sessions and the auth model turned on.
You must be sure that all views (REST and non-REST) require authentication.
For non-REST, it's easy. You simply use a basic #login-required decorator everywhere.
For the Django-REST Framework, read this: http://django-rest-framework.org/library/authentication.html#module-authentication.
You have to use the authentication mixin to be sure that authentication actually happened.
The framework supports BASIC Authentication, which requires an SSL connection to be secure. It's not too difficult to implement DIGEST authentication, which doesn't require SSL.
Avoid sessions. It violates a principle of REST to login and logout. The framework supports sessions, but it's less than ideal.
Once you have all requests authenticated, you'll know the user.
If you know the user, then user.video_set works perfectly. You can also use Video.objects.filter(...) to be sure that you're querying the user, but it's easier to confirm the code is correct if you work with user.video_set.get(...) or user.video_set.filter() or whatever.
All the relevant authorization checking is done in Views. You're providing Views for your ModelResources.
These are "class-based views". Documentation is here: https://docs.djangoproject.com/en/dev/topics/class-based-views/#viewing-subsets-of-objects
The trick is to pick all the right mixing and serializers.
For example, you can mixing get processing this way:
http://django-rest-framework.org/howto/mixin.html
You'll implement the filter in the get method

Should I use Django's Admin feature?

I'm building a Django-based review website where public users create all of the content on the site. Users create reviews for given items and they also create the items themselves that will be reviewed (providing a description and brief summary of the item, along with a few tags).
My question is this: Should I be using Django's admin features for this website (as in, exposing admin controls to the public users)? Or should I just stick with normal forms? I'm not too familiar with the admin-aspect of Django, and so far I've just been using forms for the website, but I've seen a lot of people talking about Django's admin features, and I'm starting to wonder if I should be using them.
Thanks for any feedback!
Maybe. If the admin functionality covers most of what you want to offer, there's no reason why you shouldn't use it as a starting point.
django.contrib.admin is an application like any other, and provides basically a CRUD interface to your models. Access can be controlled via groups/permissions, just like you would for an application you write yourself. You can give full access to a model with a one-liner, but obviously will have to configure properly when opening up to others.
See also my question
Django AdminSite/ModelAdmin for end users?
and similar questions Exposing django admin to users. Harmful? and How to make Django admin site accessed by non-staff user?
Regarding arguments about the "intended use" of the admin, please note Django's security update at the end of last year: http://www.djangoproject.com/weblog/2010/dec/22/security/ regarding querystring parameters in object lists. Such an update (quote: "an attacker with access to the admin [...]") is a clear indication that the admin's implementation of the permission system is being constantly scrutinized.
No. The django admin is not intended for any end-user.
The django admin feature is intended to assist the website developer, and that is all. Even usage by site administrators is contra-indicated, although in practice most small sites get away with it since they're only talking a few people who can call on the developer personally if they get into trouble.
For your purposes, the review items and the workflow in creating the items is a critical part of your application feature set. The admin will give you ideas, but it would be a mistake to attempt to build your application upon it.
I wouldn't expose the admin interface to regular users. You can use the authentication and user-management side (for your purposes), but it's usually best practice to give users a separate way to manage their objects. You also don't run as much of a risk of granting the wrong privileges to users (or allowing them to grant their own).
Have a read though the docs if you want a better overview about what it can do.

Restrict permissions after token-based authentication

A site I am working on (using django) requires that users can access a subset of the functionality temporarily by following a URL sent by email, instead of having to login properly (i.e. with username and password).
I am, of course, aware of the potential security issues with this proposal. Therefore, the tokens included in the url are randomly generated and stored on the server (instead of hashing the username or something similar), and expire.
In addition, I would like to restrict the permissions of users accessing the site through such a token URL, so that they can only access some (very limited) information, while their credentials are required for any more substantial actions.
I had implemented this in a rather crude way: Briefly, instead of authenticating the user through the token, it is stored as a session variable, and the few views that recognize the token validate it. However, it would be great to have an extended solution: For example, a global user.has_token check would be brilliant. I can't imagine, however, how a more elegant solution might be achieved.
So my question is: How would you implement such a system? Is it, for example, possible to temporarily allocate or restrict permissions in django? Might a custom middleware be necessary here?
Any help would be much appreciated. Thanks a lot!
Edit: Following the discussion below, I would like to further specify the question: Would it be efficient to assign groups through a middleware on every page view? Would it be feasible to add properties to the user object at run-time (similar to the user.has_token example above)?
usings django groups you can restict access
below link gives you the example:
http://bradmontgomery.blogspot.com/2009/04/restricting-access-by-group-in-django.html