Implement secure two-factor authentication for the login page using the Django form wizard

So basically I want to achieve something similar to Google's two-factor authentication. My login form consists of a wizard with 2 steps:

  • Step 1 (check username and password)
  • Step 2 (Security Token Authentication)

Usage Scenarios:

  • The user has a security token associated with his account: logs in the user if the user goes through steps 1 and 2
  • The user does not have a security token: writes the user to the right after he passes only step 1

I am subclassing the django Form Wizard, which will now be used as my login. In step 2, by default, Django FormWizard will include the field values ​​from previously submitted forms as hidden fields. But, as you know, the password is entered in step 1, so I do not want to enable it in step 2 for security reasons.

My first thought was to use a session to indicate whether the user has gone through Step 1, so I don’t need to include the field values ​​from step 1, but I can ignore something at all. What are safer solutions for this?

Also, I do not quite understand the use of the security hash in FormWizard. Can someone explain?

Many thanks.

+8
authentication django django-formwizard
source share
5 answers

I do not quite understand the meaning of the security token, but it would be easier and faster if you FormWizard to expand FormWizard and simply implement it as two separate types. The whole point of FormWizard is to split and merge several forms into one, and your specific use case goes against it - you just hacked it to functionally do something otherwise.

Regarding the security hash, it computes the hash for all form data from successfully completed steps. This is just a safety measure to ensure that the form data has not changed / been tampered with between the steps and that none of the steps were otherwise circumvented.

+3
source share

Duo Security duo_web project has an open source Django demo that will show you one way to do this (I'm a Duo developer).

The demo installation has a @duo_auth_requried decorator, similar to the built-in @login_required, which checks the session cookie, indicating that the user has authenticated the second factor. The @login_required decoder checks the local authentication, the @duo_auth_required decoder checks the authentication of the second factor and the absence or redirects the user to the appropriate form.

The difference with your description is that we do not authenticate in one form or transfer credentials between forms, we do them separately. Just protect the view with both decorators, and you can rely on Django to claim local authentication before trying the second auth factor.

+5
source share

More than a year after the last answer:

Django-two-factor-auth is based on django-otp and adds out of the box support for Google Authenticator, Twilio SMS, backup codes. Very impressive.

+3
source share

The django-otp project adds pluggable two-factor authentication to Django. It can be integrated at various levels: from presentation to form to a low-level API.

+1
source share

You can use an existing multi-factor authentication server such as LinOTP or privacyidea . I created a django-plugin entry.

0
source share

All Articles