I have a django app which uses the ms_identity_web repository (https://github.com/Azure-Samples/ms-identity-python-samples-common) to authenticate against an Azure Active Directory. Authentication works fine, but when i directly (not logged in) browse to a page that requires the user to be logged in (using the provided @ms_identity_web.login_required decorator) I get a 401 error instead of being redirected to my login page (as i'm used to with the Django @login_required decorator and LOGIN_URL setting's variable).

As I cannot find much documentation on this topic I resolved to writing a custom middleware (which sounds like it shouldn't be neccesary, but again; i couldn't find an option like MS_LOGIN_URL that should/is included in the repo).

Where I'm stuck is that I need to find out whether the requested page/path requires login or not (basically if it has the decorator or not).

The best solution would be one that's included in the library of course, but other solutions are welcome.

I followed the tutorial on: https://learn.microsoft.com/en-us/training/modules/msid-django-web-app-sign-in/2-register-web-app-in-azure-active-directory-tenant

In my settings.py I added:

from ms_identity_web.configuration import AADConfig
from ms_identity_web import IdentityWebPython

AAD_CONFIG = AADConfig.parse_json(file_path='aad.config.json')
MS_IDENTITY_WEB = IdentityWebPython(AAD_CONFIG)
ERROR_TEMPLATE = 'auth/{}.html`

I have a view with the decorator:

ms_identity_web = settings.MS_IDENTITY_WEB

@ms_identity_web.login_required
def view_data(request):
    context = {
        'data': 'test'
    }
    return render(request, 'data_management/view_data.html', context)`

The middleware class (added to the end of my middleware in settings.py) I came up with:

from django.shortcuts import redirect
from django.urls import reverse
from django.conf import settings
from django.urls import resolve

ms_identity_web = settings.MS_IDENTITY_WEB

class MsLoginUrlMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

def __call__(self, request):

    if resolve(request.path).url_name == 'view_data': # This should check whether the decorator is present or not
        print('view data url found')

        if request.identity_context_data.authenticated is False:
            print('step 1:login required:')
            
            if request.path.startswith('/auth/sign_in') is False:
                print('step 2: auth required, sending to login page..')
                return redirect('/auth/sign_in')
            else:
                print('user should log in now..')
                return self.get_response(request)
        
    return self.get_response(request)
0

There are 0 answers