Reputation: 6301
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
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
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