Authorization header missing in django rest_framework, is apache to blame?
ApacheApache2AuthorizationMod ProxyDjango Rest-FrameworkApache Problem Overview
I've managed to extend TokenAuthentication
and I have a working model when using the request session to store my tokens, however when I attempt to pass Authorization
as a header parameter as described here, I noticed that my Responses come back without the META variable HTTP_AUTHORIZATION. I also noticed that if I pass "Authorization2" as a header parameter that it is visible in the request:
{
'_content_type': '',
'accepted_media_type': 'application/json',
'_request': <WSGIRequest
path:/api/test_auth/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{
'MOD_AUTH_CAS_S': 'ba90237b5b6a15017f8ca1d5ef0b95c1',
'csrftoken': 'VswgfoOGHQmbWpCXksGUycj94XlwBwMh',
'sessionid': 'de1f3a8eee48730dd34f6b4d41caa210'
},
META:{
'DOCUMENT_ROOT': '/etc/apache2/htdocs',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTPS': '1',
'HTTP_ACCEPT': '*/*',
'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
'HTTP_AUTHORIZATION2': 'Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4c',
...
My first guess is that the authorization header is being removed by apache, and I have read a few S/O questions that state that apache will throw out the value if it does not match basic authorization and authenticate, but I have no idea how to allow the Authorization header to 'pass through' to Django and the WSGIRequest. Does anyone know how to solve this problem?
I also use mod_auth_cas and mod_proxy, if that changes anything..
Apache Solutions
Solution 1 - Apache
If you are using Apache and mod_wsgi, then I found the easy solution to this in the official Django REST framework website
>Apache mod_wsgi specific configuration > >Note that if deploying to Apache using mod_wsgi, the authorization header is not passed through to a WSGI application by default, as it is assumed that authentication will be handled by Apache, rather than at an application level. > >If you are deploying to Apache, and using any non-session based authentication, you will need to explicitly configure mod_wsgi to pass the required headers through to the application. This can be done by specifying the WSGIPassAuthorization directive in the appropriate context and setting it to 'On'.
# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On
Solution 2 - Apache
Sorry to answer my own question minutes after asking it. But it turns out it was apache2 after all! After crawling the webs and looking through a few search results I found this in a comment:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
Adding the above lines to my conf file seemed to solve all of my problems! Hopefully this helps users down the road!
Solution 3 - Apache
It depends on which kind of Django/Apache deployment you did. You need to tell the correct Apache module to allow to pass "Authentication" HTTP header:
-
Apache/mod_wsgi:
WSGIPassAuthorization On
-
Apache/mod_fcgid:
FcgidPassHeader Authorization
In other words: many Apache modules filters "Authentication" HTTP header, so Django will not receive it. You have to be sure your Django App is receiving it in request.
See: django_rest doc and Apache fcgid doc.
NOTE:
After modifying Apache configuration you'll need to restart apache daemon or tell to reload your .cgi file (i.e: touch my_site_fcgifile.fcgi
).
Solution 4 - Apache
The issue is the underscore in the HTTP header HTTP_AUTHORIZATION
. Most webservers just ignores the headers with underscores.
Django dev server also exhibits the same, omitting headers with underscores.
This is the reason why Authorization2
works.
A Quick work around is to replace _
underscores in headers with -
dashes,
Ex. changing the HTTP_AUTHORIZATION
to HTTP-AUTHORIZATION