damio
damio

Reputation: 6301

Basic auth with Django not working

I'm having trouble using basic auth with django, here's my config:

MIDDLEWARE_CLASSES = [
    'request_id.middleware.RequestIdMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware', # <<<<<===
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

AUTHENTICATION_BACKENDS  = [
    'django.contrib.auth.backends.RemoteUserBackend',
    'django.contrib.auth.backends.ModelBackend',
]

and my view:

def api_list_things(request, intake_id=None):
    if not request.user.is_authenticated():
        return JsonResponse({'message': 'Not authenticated'}, status=403)
    return JsonResponse({'message': 'ok'})

But when I do curl -v http://user:pass@localhost:8000/api/list_things/ I get the unauthenticated error:

* Hostname was NOT found in DNS cache                    
*   Trying ::1...                                        
* connect to ::1 port 8000 failed: Connection refused    
*   Trying 127.0.0.1...                                  
* Connected to localhost (127.0.0.1) port 8000 (#0)      
* Server auth using Basic with user 'd'                  
> GET /trs/api/intakes/ HTTP/1.1                         
> Authorization: Basic dXNlcjpwYXNz                              
> User-Agent: curl/7.38.0                                
> Host: localhost:8000                                   
> Accept: */*                                            
>                                                        
* HTTP 1.0, assume close after body                      
< HTTP/1.0 403 Forbidden                                 
< Vary: Cookie                                           
< X-Frame-Options: SAMEORIGIN                            
< Content-Type: application/json                         
< Connection: close                                      
< Server: Werkzeug/0.11.10 Python/3.4.2                  
< Date: Wed, 20 Jul 2016 14:16:32 GMT                    
<                                                        
* Closing connection 0                                   
{"message": "Not authenticated"}%                        

I don't see where I'm wrong, maybe somebody can help me ?

Upvotes: 0

Views: 2790

Answers (2)

Shubham Shingare
Shubham Shingare

Reputation: 11

import basicauth
from django.contrib.auth import authenticate

def api_list_things(request, intake_id=None):
    user_pass = basicauth.decode(request.META['HTTP_AUTHORIZATION'])
    if authenticate(username=user_pass[0], password=user_pass[1]):
        return JsonResponse({'message': 'Authenticated'}, status=200)
    return JsonResponse({'message': 'Not Authenticated'})

Upvotes: 1

Kedar
Kedar

Reputation: 1698

Django does not support Basic HTTP auth by itself, what django.contrib.auth.backends.RemoteUserBackend actually does is described in the docs.

With this setup, RemoteUserMiddleware will detect the username in request.META['REMOTE_USER'] and will authenticate and auto-login that user using the RemoteUserBackend.

The REMOTE_USER env variable should be set by a web server sitting in front of Django (for eg. apache).

If you just want to support the Authorization header, this custom authentication backend might help: https://www.djangosnippets.org/snippets/243/ (from here)

Upvotes: 2

Related Questions