Django & Two Factor Authentication (2FA)

762 views
Skip to first unread message

pokecho

unread,
Mar 23, 2011, 4:52:21 PM3/23/11
to Django users
I am writing to ask whether it is possible to configure
"django.contrib.auth" so that it can implement Two Factor
Authentication to step up login security.

The idea is that instead authenticating against just "username" and
"password" one could add another field say "passcode" which would
receive a dynamic token or PIN for additional security.

I have tried to extend "User" by subclassing, while noting that there
a couple of objections to this approach. I'm not a fan of monkey-
patching and I am not quite sure adding fields using the documented
'ForeignKey' extension strategy will do the trick. In any case, when I
try to login as admin after all the grunt work of subclassing, Python
spits out all sorts of exceptions including the nefarious *None Type*
-- 'None Type' object has no attribute 'DoesNotExist'.

Finally, assuming we can effectively implement 2 Factor
Authentication, how would we ensure that the admin adapts to 2FA i.e.
that its login form contains an additional "passcode" field for user
token/PIN input and verification.

I am new to Django, but not to Python so any assistance in this matter
will be highly appreciated. Hacking this is like trying to resolve a
rubix cube with one hand. So help me out here if you can.

Patrick

Sam Lai

unread,
Mar 24, 2011, 5:04:14 AM3/24/11
to django...@googlegroups.com
On 24 March 2011 07:52, pokecho <pok...@gmail.com> wrote:
> I am writing to ask whether it is possible to configure
> "django.contrib.auth"  so that it can implement Two Factor
> Authentication to step up login security.
>
> The idea is that instead authenticating against just "username" and
> "password" one could add another field say "passcode" which would
> receive a dynamic token or PIN for additional security.

Is a separate passcode field really necessary? Of all the 2FA auth
systems I've used, most ask the user to concatenate their
user-selected PIN and the generated code together to form the
password.

The only exception that I've encountered is 2FA Windows
authentication, and that was because the login screen still needed to
pass the user's Windows credentials on to the Windows logon process so
it could authenticate the user itself using the username and password
before logging them in. The extra password doesn't add much security;
it is only there to placate Windows requirements.

If you can repurpose the password field to be a PIN + token value
field, then a custom auth backend would be simple and all that's
required.

> I have tried to extend "User" by subclassing, while noting that there
> a couple of objections to this approach. I'm not a fan of monkey-
> patching and I am not quite sure adding fields using the documented
> 'ForeignKey' extension strategy will do the trick. In any case, when I
> try to login as admin after all the grunt work of subclassing, Python
> spits out all sorts of exceptions including the nefarious *None Type*
> --  'None Type' object has no attribute 'DoesNotExist'.
>
> Finally, assuming we can effectively implement 2 Factor
> Authentication, how would we ensure that the admin adapts to 2FA i.e.
> that its login form contains an additional "passcode" field for user
> token/PIN input and verification.
>
> I am new to Django, but not to Python so any assistance in this matter
> will be highly appreciated. Hacking this is like trying to resolve a
> rubix cube with one hand. So help me out here if you can.
>
> Patrick
>

> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to django-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>
>

pokecho

unread,
Mar 24, 2011, 9:50:57 AM3/24/11
to Django users
Hi Sam,

Thanks for the note. All the 2FA systems I have used have single field
for both the password and the token.

>Is a separate passcode field really necessary?

However, from a usability standpoint I believe decoupling the two
would make it easier for the user to recognize that the token/PIN is
fed to and consumed by the system through a different field. So I am
thinking about balancing usability and security. If the token and
password live in the same field, we increase the margin of error for a
non-techie user who must enter a known value(the password) and a
dynamic (possibly all numeric) value (i.e. the token).

>The extra password doesn't add much security; it is only there to placate Windows requirements.

Aside from Man-In-the-middle attacks and Trojan raider, which present
challenges for all authentication protocols, the security is
heightened because the second value is dynamic and expires after a
specified time.

So how do I configure contrib.auth to authenticate against three input
values "username"(static), password(static/encrypted) and PIN/
token(dynamic/encrypted)? That is the question.

Patrick

On Mar 24, 5:04 am, Sam Lai <samuel....@gmail.com> wrote:

Łukasz Rekucki

unread,
Mar 24, 2011, 4:03:53 PM3/24/11
to django...@googlegroups.com
On 24 March 2011 14:50, pokecho <pok...@gmail.com> wrote:
> Hi Sam,

>
>
> So how do I configure contrib.auth to authenticate against three input
> values "username"(static), password(static/encrypted) and PIN/
> token(dynamic/encrypted)? That is the question.

As Sam already said, you need to write a custom authentication
backend[1] and use it instead of the default one.

Of course, you'll also need a custom form on your login page. If you
want to use the same system in Django's admin, you'll need to create
your own subclass of AdminSite and override the form and template
used[2].


[1]: http://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authentication-backend
[2]: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite.login_form

--
Łukasz Rekucki

pokecho

unread,
Mar 24, 2011, 11:15:20 PM3/24/11
to Django users
Hi Łukasz,

Thanks for the great advice and for pointing me to these resources.
I truly appreciate it.

Patrick.

On Mar 24, 4:03 pm, Łukasz Rekucki <lreku...@gmail.com> wrote:
> On 24 March 2011 14:50, pokecho <poke...@gmail.com> wrote:
>
> > Hi Sam,
>
> > So how do I configure contrib.auth to authenticate against three input
> > values "username"(static), password(static/encrypted) and PIN/
> > token(dynamic/encrypted)? That is the question.
>
> As Sam already said, you need to write a custom authentication
> backend[1] and use it instead of the default one.
>
> Of course, you'll also need a custom form on your login page. If you
> want to use the same system in Django's admin, you'll need to create
> your own subclass of AdminSite and override the form and template
> used[2].
>
> [1]:http://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authenti...
> [2]:http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contri...
>
> --
> Łukasz Rekucki
Reply all
Reply to author
Forward
0 new messages