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
Related
I'm trying to design a good RESTful API for my web app and am looking at Facebook's Graph API as an example.
My plan is to dogfood the API in the web app. For example, if the user changes their name, gender, etc., on the settings page, it would just PUT to the /user endpoint of my web app with the new data.
However, I noticed that Facebook's Graph API does not allow modifications to the User resource. Are there some resources that you want to make sure are not modifiable from the public API?
I'm basically just wondering if there are any risks with my method, and if not, why other websites don't do the same thing.
Yes, there are resources that you want to prevent API users from modifying, but they are application dependent. For instance, an API I'm working on right now lets callers read but not update audit data, read user records (but only modify parts of their own), and create and update home addresses.
You will want to make sure that you have rigorous security in place to prevent users from modifying certain parts of a User (such as username or password), especially if user A is calling PUT /users/B.
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
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).
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
I have a website (the basic gist of which is described in this question), and I want to have some way to store the username and some information about the user consistently while they use the site (ie, upload and download data).
Right now, given a successful login, I was returning the hash of the password as well as any associated information. Anytime a user tries something, their username, hash, and so forth must match what's in the database. If the user logs out, their local Sinatra session has all information flushed.
I realize that this is a very naive approach. Is there a better way to handle user session information? The wikipedia entry on cookies mentions that a session uid is used instead of this other information; what is the advantage of that approach? I suspect that this approach is also vulnerable to other attacks, but since I verify everything that's done as it's done, I'm not sure what attacks I'm leaving myself open to.
Also, if/when I implement ssl, will these transactions be 'automagically' encrypted, or will I need to do something else to make sure that the strings are protected, if they need to be?
This is actually a very complicated issue. Just to illustrate, you have the problem of account lock-out: If you lock out based on failed attempts, how easy is it for an attacker to DOS your website?
I'll list a few best-practices to get you started:
Store Passwords Salted and Hashed alongside the Username and UserId. (You should also store the salt next to the hash.)
Disallow frequent bad-password attempts. (More frequent than once every few seconds).
If attempts are failing for any given user or any given IP address (more than 3 times a minute) require some form of human-validation, like a CAPTCHA. This allows you to prevent total DOS attacks.
If implementing an auto-login system, use a token authentication system.
For token authentication systems, use a Secure random number generator, send the plain token to the users, but Salt and Hash the token at the database.
Use TLS/SSL if possible, but don't rely on their security once the data is off-the-wire.
If your website is built in asp.net then you can use dot net securities.. which is really very good. and you can also use principle classes in it to make it more secure..