DEV Community

Cover image for Fingerprint-based authentication and Authorization in Python(Django) web applications - Hacking your way out (Part 3)
John Owolabi Idogun
John Owolabi Idogun

Posted on • Updated on

Fingerprint-based authentication and Authorization in Python(Django) web applications - Hacking your way out (Part 3)

Here comes the concluding part of this series. In this part, we'll focus on extending the registration flow of the third-party application we have been using to implement the specification we want for our app.

NOTE: This section is optional and as a result, it was not included in this tutorial's github repository. The feature was also not incorporated in its live version

The specification we'll be addressing says that if a user fails to identify himself/herself using his/her device's authenticator or external authenticator(s) supported by python-fido2, such user should be removed from the database, logged out of the application and then redirected to the registration page to restart the process. This is to ensure that only verified users who used the supported attestation formats during registration are authenticated and authorized.

Unfortunately, django-mfa2 was not built to support that out-of-the-box. However, to add this feature, one needs to have a local version of the application so as to be able to extend its functionalities.

Going by the idea stated above, we need to move the mfa package which should be located in site-packages directory of your virtual environment folder. The path to mine is django-mfa-example/env/lib/python3.8/site-packages.

It should be noted that you may not be able to get this path if you used pipenv for your virtual environment. One option you have, in this case, is to download the mfa application and move it to your application directory.

Now to the codes. A careful inspection of mfa's source code reveals that most of the redirections, in case of failure, can be intercepted in the script section of the FIDO2/Add.html file located in its templates directory. We'll be modifying line 37 and line 40.

First, to address removing and logging out users, append this function to your accounts/ file:

def remove_user_and_redirect(request):
    messages.error(request, f'Your fingerprint capture was not valid. Kindly re-register and try again.')
    return redirect(reverse('accounts:register'))
Enter fullscreen mode Exit fullscreen mode

This simply fetches out the user using its username and deletes it from the database using Django ORM's delete() method. Then, such user will be logged out using one of Django's auth methods, logout. An error message will then be flashed to inform the user of the action taken and finally, redirected to the registration page.

Add this view function to your accounts/

urlpatterns = [
    path('remove_user_and_redirect', views.remove_user_and_redirect, name='remove_user_and_redirect'),
Enter fullscreen mode Exit fullscreen mode

Now, proceed to the lines pointed out earlier (line 37 and line 40) and append the following:

setTimeout(function () {
  window.location.href = "{% url 'accounts:remove_user_and_redirect' %}" }, 1000);
Enter fullscreen mode Exit fullscreen mode

to each of the lines.

There is nothing much here. We just instruct the app to wait for about 1000ms so that the user can read the error message outputted and then redirect automatically by calling the function added above through the url, accounts:remove_user_and_redirect. setTimeout() method executes a function or specified piece of code once the timer expires.

Hurray!!! We have come to the end of this rather long piece. Hope you learned something.

Do you have any suggestions, comments or reactions? Kindly drop them in the comment section below. Let's keep learning and practicing.


Top comments (3)

ionelx25 profile image

I have managed to install your app on centos 8 stream.
I am clicking on registration link but I am getting error:
Registeration Failed as TypeError: Cannot read properties of undefined (reading 'create')
The only changes done was removing from accounts\
if not username.isalnum():
return False

if not username.lower().startswith("cpe"):
    return False
Enter fullscreen mode Exit fullscreen mode

The login works with any username regardless of registration. No MFA fingerprint scan so far.
Thank you !

ionelx25 profile image

I have managed to fix that problem by going in production mode (https).
Now I have another issue.
I am registering the fingerprint all ok. But login works with any fingerprint. I'll debug more the login part but I guess it should work.

dimosojunior profile image
Dimoso Junior

Sorry, which kind of fingerprint I can use to register and authenticate user in my Django project?