'Django to catch all invalid logins and unauthorized access like 401s and 403s

I want to capture all invalid logins/unauthorized access such as 401s and 403s returned from the site so I can log them to a security logging service, investigating if there is an easy way to catch all of these without putting in much custom logic.

I have tried using middleware approach:

def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):

        response = get_response(request)

        if response.status_code in [403, 401]:
            log.warning('invalid login')

        return response

    return middleware

Unfortunately an incorrect login to the /admin/ login, it returns status 200, however I think this would work for custom login that explicitly throws 401/403.

I have also tried using the signal approach using request_finished but all I get is just the handler class.

So... looking for ideas.



Solution 1:[1]

As you found out, a login attempt doesn't necessarily imply a specific response code, since you may decide to treat the attempt with a redirect or any other type of answer.

In case of Django, the default auth middleware (which I assume you are using) fires a user_login_failed signal which you can handle with your logging logic.

You can see in the documentation how to register a signal handler, so it should be something like

from django.contrib.auth.signals import user_login_failed
from django.dispatch import receiver

@receiver(request_finished)
def handle_login_failed(sender, **kwargs):
    print(f"Oops, login failed using these credentials: {kwargs.get('credentials', None)}")

The signal triggering is in the source code for the auth package.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Miguel Ventura