Fingerprint-based authentication and Authorization in Python(Django) web applications
John Owolabi Idogun
Posted on June 8, 2021
Passwords, as great as they have been, have some setbacks, both for users and developers. Applications users tend to always worry about passwords being stolen by phishing tools, or their passwords being leaked online when used on compromised websites. Aside this, they also have to worry about creating and remembering passwords even in contemporary times when password management tools are prevalent. At the flip side of it, Developers have to worry about all the complications of passing passwords through systems and safely storing them in databases. All these, among others, prompted W3C and FIDO as well as other tech juggernauts such as Google, Mozilla, Microsoft and Yubico to put forward a new authentication paradigm which allows biometric and other cryptographic means to authenticate users. It is aptly known as WebAuthn.
Modern browsers support this awesome technology and there are a couple of its implemetations in various major programming languages and web frameworks. However, this series of tutorials will only focus on implementing it in a Django application using a wonderful django package, django-mfa2 which utilizes python-fido2 under the hood.
A simple fingerprint-based authentication and authorization application using django-mfa2
django_mfa2_example
Fingerprint-based authentication and authorization system in Python (Django). This can be integrated with e-voting systems and other applications that should be very secure.
Please note that we won't be that particular about the looks of the application. In fact, it was built using bootstrap5's example templates. It is assumed you have atleast gone through Django tutorial or are familiar with Django.
Now, let's get started.
Fire up your terminal and navigate or create the directory you will be working on. As for me, I have already created django-mfa-example and have activated my virtual environment using pipenv.
Proceed to your project's INSTALLED_APPS in settings.py file and append mfa and accounts.apps.AccountsConfig to it as shown below:
# django_mfa_example > settings.py
INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','mfa',#add this for django-mfa2
'accounts.apps.AccountsConfig',#your local app
]
Configure your STATICFILES_DIRS, and STATIC_ROOT. Create static and templates folders at the root of the application and connect them appropriately in your settings.py file.
If you are lost, check the code on github to guide you.
In your accounts app, create a urls.py file and link it to your project's urls.py. Also, to use django-mfa2, you are required to add it to your project's urls.py.
fromdjango.contribimportadminfromdjango.confimportsettingsfromdjango.conf.urls.staticimportstaticfromdjango.urlsimportpath,includeimportmfaimportmfa.TrustedDeviceurlpatterns=[path('admin/',admin.site.urls),path('mfa/',include('mfa.urls')),#required to use mfa
path('devices/add/',mfa.TrustedDevice.add,name="mfa_add_new_trusted_device"),#required if you intend adding some devices
path("",include('accounts.urls',namespace='accounts'))#include accounts with namespace
]ifsettings.DEBUG:urlpatterns+=static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
instructs django to serve the static files during development only or when DEBUG is True.
Now, let's add some mfa specific configurations to our project's settings.py
MFA_UNALLOWED_METHODS=()# Methods that shouldn't be allowed for the user
MFA_LOGIN_CALLBACK="accounts.views.login_user_in"# A function that should be called by username to login the user in session
MFA_RECHECK=True# Allow random rechecking of the user
MFA_RECHECK_MIN=10# Minimum interval in seconds
MFA_RECHECK_MAX=30# Maximum in seconds
MFA_QUICKLOGIN=True# Allows quick login for returning users
TOKEN_ISSUER_NAME="django_mfa2_example"#TOTP Issuer name, this should be your project's name
ifDEBUG:U2F_APPID="https://localhost"#URL For U2F
FIDO_SERVER_ID=u"localhost"# Server rp id for FIDO2, it is the full domain of your project
else:U2F_APPID="https://django-mfa2-example.herokuapp.com"#URL For U2F
FIDO_SERVER_ID=u"django-mfa2-example.herokuapp.com"# Server rp id for FIDO2, it is the full domain of your project
FIDO_SERVER_NAME=u"django_mfa2_example"MFA_REDIRECT_AFTER_REGISTRATION='accounts:index'MFA_SUCCESS_REGISTRATION_MSG='Your keys have successfully been created! You '
Since we would like to make the application production-ready, notice the inclusion of these lines:
ifDEBUG:U2F_APPID="https://localhost"#URL For U2F
FIDO_SERVER_ID=u"localhost"# Server rp id for FIDO2, it is the full domain of your project
else:U2F_APPID="https://django-mfa2-example.herokuapp.com"#URL For U2F
FIDO_SERVER_ID=u"django-mfa2-example.herokuapp.com"# Server rp id for FIDO2, it is the full domain of your project
If you are going to have a different domain name, edit the else block accordingly.
To wrap up this part, let's include some basic settings to our accounts application.
First off, populate accounts/urls.py with the following:
In the code, we are inheriting from AbstractUser and appending diaplay_name field to our User table. To know about the reason I used AbstractUser and not AbstractBaseUser, read this Vitor Freitas's article and Michael Herman's Creating a Custom User Model in Django.
To make Django aware of this new user model, proceed to your settings.py file and add:
AUTH_USER_MODEL='accounts.User'
If your application name isn't accounts and/or your new model isn't User, change the line above to:
A simple fingerprint-based authentication and authorization application using django-mfa2
django_mfa2_example
Fingerprint-based authentication and authorization system in Python (Django). This can be integrated with e-voting systems and other applications that should be very secure.
Enjoyed this article? I'm a Software Engineer and Technical Writer actively seeking new opportunities, particularly in areas related to web security, finance, healthcare, and education. If you think my expertise aligns with your team's needs, let's chat! You can find me on LinkedIn and Twitter.
If you found this article valuable, consider sharing it with your network to help spread the knowledge!