How to implement a manual security procedure with Django - django

I'm writing a web application with Django framework. This web application is API based and I'm using Django rest_framework. I have a security issue: On the first page, the user must solve a Recaptcha. After solving the Recaptcha my site gives a session ID to the user and after this, the user must post this session ID in the body of all his/her API calls and every API can be called just once with a specific session ID. In other words, I have a state machine for the APIs being called by the user and in each state, the user can call the APIs which have corresponding outgoing edges from that state.
The purpose of all of the above procedures is preventing the user from crawling my website. (User can't call an API many times with a session ID and he/she should act as a normal user and call every API at most two or three times)
Now my question is that how should I handle this in my Django app? Before this, I just used the ordinary Django session middleware for handling sessions. Now should I handle the authentication process and passing and getting session ID completely in a manual way or is there a way in which I can use that middleware that it can be able to handle my procedure.

You can do this with simply with saving your user's state and in each step update your user's state and consider the next states which user can see.

Use custom permission classes for your APIViews to block such request.
Read more here https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

Related

Flask authenticantion. How to inform the user logged in the client to the server

I am creating a flask app to be used internally in my company. I would like to restrict what a user can do it based on its login ID. I read a lot about using LDAP3 but I don't think I can do what want which send the login ID to the server. There I would have a table which will register which part of the system has the permition to edit. If it try to change somenthing not permited the app will retrieve a warning message.
I won't to do that to avoid having to create a separate login functionality just for this app. I read that I should use AD authentication but I am not very familiarized with that and I would also like to avoid having to ask our IT department to create user groups there for each part of my system.
I know that I can do that using ASP .NET (at least I did once).
Any guidance will be apreciated.
I think you are looking for Role-based Authorization.
In order to use this functionality you will need to implement roles on your model file per the Data-models documentation.
This will allow you to assign users a role when they are created, and you can use a decorator on your routes to 'require' the user to have the role you want them to have before they access the endpoint.

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.

How to check session for all views in Django?

I set the session["UserID"] for user login status in view login page after pass the verify of username and password.
Then I need to check if the user is logged in within every other views, such as home page, shopping bag page and so on.
My question is, can I check it just for one time and where should I write it? Are there some methods triggered before the views called?
My question is, can I check it just for one time and where should I write it?
You do check it one time, providing you are using django's built in authentication method then the whole handling of users is done for you, you don't need session user id's since django handles the user through requests with its auth middleware.
Once logged in there will be a user as part of the request object which will either be a AnonymousUser if not logged in, or an instance of your user class if you are logged in.
Are there some methods triggered before the views called?
Yes, middlewares, which you could write your own custom middleware but I don't really think you need it.
I check the login status within the MASTER PAGE in ASP.NET and it can control all the other page which import it.
I haven't really used asp.net but again, you don't need to do this, django handles its users for you (providing your using built in auth tools).
See Limiting access to logged-in users and the functions and properties available on the user class

How do I authenticate remotely in 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!

Hints for the logic of django app

I'm learning Django and for this reason I'm developing an application described below.
This application allows users (authenticated and anonymous) to send message to other users.
Authenticated users can send message and can track all messages simply as all application that uses this feature. (like Facebook messages, for example)
The problem are anonymous users. I would an anonymous user can send message to other users but he can track his messages only for his session. Users can also reply to a message of an anonymous user but If an anonymous user lost his session lost also his messages.
The problem is, how can I manage anonymous user and their messages for the session only?
Django supports anonymous sessions.
If your app is relatively simple (it sounds like it is), I would do the following:
Create a standard Django user profile model and link that to the users messages but do not use OneToOne to connect to User.
Use database backed sessions (https://docs.djangoproject.com/en/dev/topics/http/sessions/#using-database-backed-sessions)
Create a temporary user profile model for anonymous users and store
their temporary profile id in their session.
Once a day delete all profile objects that do not have a user AND
whose id is not in the sessions table. A simple way (and what I would do) is have a created date/time field on the profile and just delete any profile that was created two weeks or more ago and has a null user field. I'd just crontab a django management command.
The cool thing is that if somebody registers after using the app anonymously for a while you can use their temporary profile as their profile and they keep their messages.