Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Basic Auth for one view (avoid middleware)

Tags:

I need to provide http-basic-auth to one view.

I want to avoid modifying the middleware settings.

Background: This is a view which gets filled in by a remote application.

like image 729
guettli Avatar asked Sep 26 '17 12:09

guettli


People also ask

What is GZipMiddleware?

GZipMiddleware compresses content for browsers that understand GZip compression (all modern browsers). This middleware should be placed before any other middleware that need to read or write the response body so that compression happens afterward.

Is Basic Auth still used?

Microsoft is discontinuing the use of basic authentication in Exchange Online for various applications, including but not limited to: EAS, POP, IMAP, Remote PowerShell, Exchange Web Services (EWS), Offline Address Book (OAB), Outlook for Windows and Mac.

What is the purpose of middleware in Django?

Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering Django's input or output. Each middleware component is responsible for doing some specific function.


1 Answers

When you do a basic auth request, you're really adding credentials into the Authorization header. Before transit, these credentials are base64-encoded, so you need to decode them on receipt.

The following code snippet presumes that there's only one valid username and password:

import base64  def my_view(request):     auth_header = request.META.get('HTTP_AUTHORIZATION', '')     token_type, _, credentials = auth_header.partition(' ')      expected = base64.b64encode(b'username:password').decode()      if token_type != 'Basic' or credentials != expected:         return HttpResponse(status=401)      # Your authenticated code here:     ... 

If you wish to compare to the username and password of a User model, try the following instead:

def my_view(request):     auth_header = request.META.get('HTTP_AUTHORIZATION', '')     token_type, _, credentials = auth_header.partition(' ')      username, password = base64.b64decode(credentials).split(':')     try:         user = User.objects.get(username=username)     except User.DoesNotExist:         return HttpResponse(status=401)      password_valid = user.check_password(password)      if token_type != 'Basic' or not password_valid:         return HttpResponse(status=401)      # Your authenticated code here:     ... 

Please note that this latter version is not extremely secure. At first glance, I can see that it is vulnerable to timing attacks, for example.

like image 154
meshy Avatar answered Oct 24 '22 16:10

meshy