1

I have implemented backend api using django. Environment details are as-

Environment : platform : Linux (ubuntu) framework : Django 1.11.28 programming language : python 2.7.12 (will planning to migrate 3.8 in future) Database : Mongodb 3.4

Description : I have developed web services using django. These are plain web services not Restful( earlier there wasn't full support for mongodb for Django rest framework) hence most of the things are customised not as per django standard.

Issue details : For authentication I am using Azure AD. I have written simple decorator which receives access token from request sent by front web app/mobile then this decorator validates token and return to view.For authentication I am using django-auth-adfs package

decorator

authorisation.py

def is_authorized(function):
    @wraps(function)
    def authorize(request, *args, **kwargs):
        # access token validation logic
        if validated(token):
            # get user details from access token first_name, last_name etc
            user_info = {"first_name":"foo","last_name":"bar"}
            return function(request, *args, **kwargs)
        else:
            return HttpResponse('Unauthorized', status=401)
return authorize

View.py

@is_authorized
def home_view(request):
    # calling function which decodes access token and return user details.
    # This function contains same code as in decorator except function it returns user_info
    **first_name, last_name = get_userinfo_from_access_token(request)**
return JsonResponse({"data":{"fname":first_name,"lname":last_name}})

As you can see code got messy, and repetitive code. Here in view I am not able to access user details which already decoded in view. To get user details I wrote same code in get_userinfo_from_access_token() function by passing request object, I don't think this is not near 'ok'.

  • I need approach which is as per django standard and followed by most of the django developers. Do I require to implement some authentication backend or some django middleware if yes please guide me through it.

Considering my current scenario and environment,

  1. Can you explain best and standard approach to access user details from request object
  2. There are lot of views created by me, I am adding is_authorized decorator to every view. Is there any standard and better approach to protect view.
  3. I am planning to rewrite whole code in future using django rest framework. I will be very thankful if anyone provide me some reference or guideline to achieve restful web services so that I can use my existing code and reduce my efforts.

Please let me know if I am unclear about anything and more details required. Thanks in advance.

sachin27
  • 145
  • 3
  • 13

1 Answers1

2

Well. Let me give your answer sequentially.

  1. Write a middle-ware and attach the user based on token from database query.
  2. Create another middle-ware that will allow protected path only if user is authenticated by above (1) middle-ware.
  3. As django is changing day by day, it will better if you ask separate question when you will be implementing at REST. I know the standard but answering it now may obsolete later.

Now going back to middle-wares. Middle-ware works in order. Invalid order of those may not work

1st middle-ware

class UserResolverMiddleware(MiddlewareMixin):
    """
    A middleware class that adds a ``user`` attribute to the current request.
    """

    def process_request(self, request):
        """

        get token from request header
        validate token
        decode the token
        query on db or attach a fake user with necessary decoded data. 
        attach user object to request like request.user = user
        """

2nd one.

from django.http import HttpResponseForbidden
class ProtectedViewMiddleware(MiddlewareMixin):


    def process_request(self, request):

        """
        create a list of URL which is not protected (e.g: login, forget password)
        unprotected_list = ['']
        if request url does not belongs to unprotected_list and request has no attribue user:

            return  HttpResponseForbidden()
        return 
        """
Saiful Azad
  • 1,823
  • 3
  • 17
  • 27
  • Thanks for your response. Can you elaborate about need of second middleware, what if I don't use 2nd middleware, how can this impact my security. – sachin27 Mar 17 '20 at 07:11
  • 2nd middleware works as is_authorized decorator. is user is not authenticated but want to access in protected view we just ignore them. If you do not use this middleware you have to deal with auth in every protected views. – Saiful Azad Mar 17 '20 at 09:43
  • I can put excluded url in same middleware as mentioned in 1 and that will not process for token authentication. But correct me if I write another middleware, won't it executed after first middleware. So for view which is to access by non authenticated user won't work. – sachin27 Mar 17 '20 at 09:50
  • can you provide example for second middleware as above it will clarify more and helps me to understand. Right now I am able to achieve what is expected but I want to follow standard approach. After this I can mark it as answer for my query. – sachin27 Mar 17 '20 at 10:00
  • @sachin27, plz have a look – Saiful Azad Mar 17 '20 at 10:18