how to access the request in a django custom authentication backend?
Asked Answered
F

2

10

I want to do the following with django's authentication:

  • Log incorrect log-in attempts
  • Temporarily lock accounts after 'x' number of incorrect log-in attempts
  • Log successful log-ins.

I thought a custom auth backend would be the solution.

I can do most of what i want, but I want to log the IP and REMOTE_HOST of the user making the attempt.

how can I access the request object in the auth backend?

Thanks

Forget answered 15/8, 2010 at 16:53 Comment(0)
S
11

The authentication backend can take any number of custom parameters for the authenticate() method. For example:

class MyBackend:
    def authenticate(self, username=None, password=None, request=None):
         # check username, password
         if request is not None:
             # log values from request object

If you are calling authenticate in your own view, you can pass the request object:

from django.contrib.auth import authenticate

def login(request):
    # discover username and password
    authenticate(username=username, password=password, request=request)
    # continue as normal

If you're using django's login view (or the admin login), you wont have the extra information. Put simply, you'll have to use your own custom login view.

Also, be careful when automatically locking accounts: you allow someone to deliberately lock one of your user's accounts (denial of service). There are ways around this. Also, make sure your log of incorrect attempts doesn't contain any attempted passwords.

Scarper answered 15/8, 2010 at 17:19 Comment(5)
i'm extending the ModelBackend - python doesn't allow me to overload methods does it? What would be a good way of achieving this? Just rename the 'authenticate' method and call that in my view?Forget
what do i need to put in the login view? just copy the whole of the current contrib.auth login view? I don't understand because that method never calls 'authenticate'...Forget
You can certainly overload in python. contrib.auth requires the backends to have an authenticate method, so you'll have to call it that.Scarper
Django's view calls authenticate() when validating its AuthenticationForm (in contrib.auth.forms). Django's login view also supports a number of other features which you wont need. It's not too difficult to put it in your own view, just call authenticate and login if all is good. Doing this in form validation is of course nicer, but you'll need to pass the request.Scarper
This awnser would still require me to hack into the admin because authenticate is called via a custom form which doesnt have a request attribute either..?Sacker
U
0

In recent versions of Django, authenticate() accepts "request" as first parameter:

  • optionally since Django 1.1
  • required since Django 2.1

See:

Upi answered 25/1, 2019 at 17:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.